import * as types from './mutation-types'
import * as globalTypes from '../../mutation-types'
import * as socketTypes from '../socket-push/mutation-types'
import cti from '../../api/cti'
import {getCache} from '../../actions'
import {strLineAll, m7Language, getCurrentDateTime, encrypt, getAesEncrypt} from '@/utils/m7Utils'
import * as monitorAction from '../monitor/actions'
import * as monitorType from '../monitor/mutation-types'
import * as callType from '../call/mutation-types'
import user from '../../api/user'
import { MessageBox } from 'element-ui'
let ctiIsWaitingEvent = false // 是否有事件
let ctiReconnectionCount = 0 // 轮询事件的次数
let currentPhoneBarConfig = {} // 临时存储的电话条的注册的信息，电话条重连时用
let waitError = false
let jsonpSetInterval
let ws = null
let isWebsocket = false
export const getWSSupport = ({commit, state, rootState, dispatch}, config) => { // 判断是否支持WS
  commit(types.CTI_URL, config.proxy_url)  // 当前账号所在的pbx配置里的url，使用位置：电话条jsonp请求&&心跳图请求（计费位置：资源 =》 呼叫中心 =》 pbx管理 =》 pbx详情中的路由ip)
  let sendData = {
    Command: 'Action',
    User: config.user,
    Action: 'GetWSSupport'
  }
  cti._cti_sendAction(sendData, state).then(resp => {
    if (resp && resp.Succeed) {
      if (resp.WS_PORT && ('WebSocket' in window || 'MozWebSocket' in window)) { // 支持WS，舍弃jsonp
        dispatch('registerPhoneWsEvent', {config, WS_PORT: resp.WS_PORT, WS_SECURE_PORT: resp.WS_SECURE_PORT})
        console.log('websocket')
      } else { // 没开启ws
        dispatch('ctiRegister', config)
      }
    } else { // 不支持WS，继续走jsonp
      dispatch('ctiRegister', config)
      console.log('jsonp')
    }
    isWebsocket = resp.Succeed && resp.WS_PORT ? true : false
  })
}
// ws 注册
export const registerPhoneWsEvent = ({commit, state, rootState, dispatch}, {config, WS_PORT, WS_SECURE_PORT}) => { // 初始化注册电话条
  let wsIp = config.proxy_url
  let index = wsIp.indexOf('//')
  wsIp = wsIp.substring(index + 2, wsIp.length)
  if (wsIp.indexOf(':') > -1) { // 带着端口号的舍弃端口号
    wsIp = wsIp.split(':')[0]
  }
  if (wsIp.indexOf('/') > -1) { // 只取域名，xxx.com/aaa 去除aaa
    wsIp = wsIp.split('/')[0]
  }
  let url = 'ws://' + wsIp + ':' + WS_PORT + '/websocket'
  if (document.location.protocol === 'https:') {
    WS_SECURE_PORT = WS_SECURE_PORT ? WS_SECURE_PORT : '443'
    url = 'wss://' + wsIp + ':' + WS_SECURE_PORT + '/websocket'
  }
  let lockReconnect = false
  let reconnectNum = 0
  let SessionID = ''
  let kickFlag = false
  let initWebsocket = function () {
    try {
      if ('WebSocket' in window) {
        ws = new WebSocket(url)
      } else if ('MozWebSocket' in window) {
        ws = new MozWebSocket(url)
      }
      connect.initConnect()
    } catch (e) {
      connect.reconnect()
      console.log(e)
    }
  }
  // ws 心跳检测
  let heartCheck = {
    timeout: 5000, // 5s
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
      window.clearTimeout(this.timeoutObj)
      window.clearTimeout(this.serverTimeoutObj)
      return this
    },
    start: function(){
      let self = this
      this.timeoutObj = window.setTimeout(function(){
        // 这里发送一个心跳，后端收到后，返回一个心跳消息，
        // onmessage拿到返回的心跳就说明连接正常
        if (ws.readyState === 1) { // ws正常建立连接时才发ping
          ws.send(JSON.stringify({ Action: 'Ping', SessionID: SessionID }))
        }
        self.serverTimeoutObj = window.setTimeout(function(){// 如果超过一定时间还没重置，说明后端主动断开了
          ws.close() // 如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        }, self.timeout * 8)
      }, this.timeout)
    }
  }
  let connect = {
    initConnect: function () {
      ws.onclose = function () {
        if (!kickFlag) { // 被踢出的情况，不能重连
          connect.reconnect(url)
        }
        console.log('ws连接关闭!' + new Date().toUTCString())
      }
      ws.onerror = function (event) {
        if (reconnectNum > 4 && reconnectNum % 8 === 1) { // 连接服务器超时，可能是您的网络问题，正在尝试重新连接...
          commit(globalTypes.SET_ERROR, 'cti.connectServiceTimeout')
        }
        connect.reconnect(url)
      }
      ws.onopen = function () {
        heartCheck.reset().start() // 心跳检测重置
        reconnectNum = 0
        let currentTime = getCurrentDateTime()
        let sendData = { // 登陆信息
          ipMessage: rootState.session.ipMessage,
          User: config.user,
          Monitor: config.monitor,
          ExtenType: config.extenType,
          Command: 'Action',
          Action: 'Login',
          Password: config.password,
          ActionID: 'Login' + Math.random(),
          BusyType: config.busyType,
          currentTime: currentTime,
          AppVersion: 'service'
        }
        if ((rootState.session.user.isAdmin && rootState.session.user.isAdmin === true) || rootState.session.phoneTokenInUse === true) {
          // 计费跳转或者是token登录
          sendData = {
            ipMessage: rootState.session.ipMessage,
            Command: 'Action',
            Action: 'Login',
            ActionID: 'Login' + Math.random(),
            PBX: config.curPbx,
            Account: rootState.session.account.account,
            Password: '7pu3refwds98172e',
            UserID: '2387rufhinjvcx73rfws',
            MonitorUser: true
          }
          config.userId = '2387rufhinjvcx73rfws'
        }
        ws.send(JSON.stringify(sendData)) // 获取登陆信息
      }
      ws.onmessage = function (event) { // 如果获取到消息，心跳检测重置
        let eventData = JSON.parse(event.data)
        if (!eventData.Pong && eventData.Response !== 'Ping') {
          heartCheck.reset().start() // 拿到任何消息都说明当前连接是正常的
          if (eventData.Response === 'Login') { // 登陆事件
            if (eventData.SessionID) {
              SessionID = eventData.SessionID
              config.uniqueId = eventData.SessionID
              let date = new Date()
              let identity = date.valueOf()
              config.currentServerTime = identity - eventData.Timestamp * 1000
              config.phonebarConfig = eventData.PhonebarConfig
              config.autoBusyTime = eventData.AutoBusyTime
              if (eventData.UserID) {
                config.userId = eventData.UserID
              }
              if (eventData.PBX) {
                config.pbx_in_ip = eventData.PBX
              }
              if (eventData.Account) {
                config.accountId = eventData.Account
              }
              config.loginName = config.User || config.user
              config.sipNo = eventData.SipNum
              config.monitorUser = eventData.MonitorUser
              config.monitorPassword = eventData.MonitorPassword
              ctiInit(commit, state, config) // 初始化电话条
              currentPhoneBarConfig = config // 把配置电话条的参数临时存储，用于重连电话条
            } else if (!eventData.Succeed) {
              let code = eventData.Result
              if (code) {
                if (code === 601) { // 通话座席登录数已达最大或者已经到期
                  commit(globalTypes.SET_EXIT, 'cti.agentmax')
                } else if (code === 603) { // 通话座席登录数已达最大或者已经到期,换登录方式
                  commit(globalTypes.SET_EXIT, 'cti.overdue')
                } else if (code === 602) { // 通话座席登录数已达最大或者已经到期,换登录方式
                  commit(globalTypes.SET_EXIT, 'cti.agentmaxOroverdueUserTypeLogin')
                  window.location = document.location.href
                } else if (code === 500) {
                  if (config.extenType === 'Local') { // 没有绑定手机号码,
                    commit(globalTypes.SET_EXIT, 'cti.unBindPhone')
                  } else { // 网关还没有绑定
                    commit(globalTypes.UNBINDGATEWAY, 'cti.unBindGateway')
                  }
                } else if (code === 406) { // 账号的版本与系统版本不符
                  commit(globalTypes.SET_EXIT, 'cti.systemVersionError')
                } else {
                  if (code === '400') { // 登录失败
                    commit(globalTypes.SET_EXIT, 'cti.loginError')
                  }
                }
              }
            }
            return eventData
          } else if (eventData.Response && eventData.Response.Response === 'PushState') {
            if (eventData.Event[0] && eventData.Event[0].Event === 'Kick') {
              commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
              commit(globalTypes.SET_KICK_FLAG, true) // socket是否离线
              if (eventData.Response && (eventData.Response.Comments === 'ekick' || eventData.Response.Comments === 'ukick')) { // 同时登录踢出
                dispatch('destroyWebrtc')
                commit(globalTypes.SET_EXIT, 'cti.sessionInvalidation1')
              } else if (eventData.Response && eventData.Response.Comments === 'restartKick') { // 客户正在使用系统时，状态服务器重启，6S后提示异常并且重连电话条
                window.setTimeout(function () {
                  // initWebsocket()
                  commit(globalTypes.SET_ERROR, 'cti.serviceFailToRelogin')
                }, 60000)
                return
              } else { // 管理员强制签出
                commit(globalTypes.SET_EXIT, 'cti.sessionInvalidation2')
              }
              commit(globalTypes.LOGINED, false)
              kickFlag = true
              ws.close()
              return
            }
            ctiEventHandler(eventData.Event, state, commit, rootState, dispatch)
          }
        } else if (eventData.Pong && eventData.Response === 'Ping') {
          heartCheck.reset().start() // 拿到任何消息都说明当前连接是正常的
        }
      }
    },
    reconnect: function () {
      if (lockReconnect) {
        return
      }
      lockReconnect = true
      window.setTimeout(function () { // 没连接上会一直重连，设置延迟避免请求过多
        reconnectNum++
        initWebsocket()
        lockReconnect = false
      }, 2000)
    }
  }
  initWebsocket()
}
export const ctiRegister = ({commit, state, rootState, dispatch}, config) => { // 初始化注册电话条
  // commit(types.CTI_URL, config.proxy_url)  // 当前账号所在的pbx配置里的url，使用位置：电话条jsonp请求&&心跳图请求（计费位置：资源 =》 呼叫中心 =》 pbx管理 =》 pbx详情中的路由ip)
  let phoneJson = {
    ipMessage: rootState.session.ipMessage,
    Command: 'Action',
    Action: 'Login',
    ActionID: 'Login' + Math.random(),
    ExtenType: config.extenType,
    Password: config.password,
    BusyType: config.busyType,
    Monitor: config.monitor,
    User: config.user,
    AppVersion: 'service'
  }
  if ((rootState.session.user.isAdmin && rootState.session.user.isAdmin === true) || rootState.session.phoneTokenInUse === true) {
    // 计费跳转或者是token登录
    phoneJson = {
      ipMessage: rootState.session.ipMessage,
      Command: 'Action',
      Action: 'Login',
      ActionID: 'Login' + Math.random(),
      PBX: config.curPbx,
      Account: rootState.session.account.account,
      Password: '7pu3refwds98172e',
      UserID: '2387rufhinjvcx73rfws',
      MonitorUser: true
    }
    config.userId = '2387rufhinjvcx73rfws'
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        let code = _response.Result
        if (code) {
          if (code === 601) { // 通话座席登录数已达最大或者已经到期
            commit(globalTypes.SET_EXIT, 'cti.agentmax')
            commit(socketTypes.DISCONNECT_SOCKET) // 结束socket 推送
          } else if (code === 603) { // 通话座席登录数已达最大或者已经到期,换登录方式
            commit(globalTypes.SET_EXIT, 'cti.overdue')
            commit(socketTypes.DISCONNECT_SOCKET) // 结束socket 推送
          } else if (code === 602) { // 通话座席登录数已达最大或者已经到期,换登录方式
            commit(globalTypes.SET_EXIT, 'cti.agentmaxOroverdueUserTypeLogin')
            commit(socketTypes.DISCONNECT_SOCKET) // 结束socket 推送
          } else if (code === 500) {
            if (config.extenType === 'Local') { // 没有绑定手机号码,
              commit(globalTypes.SET_EXIT, 'cti.unBindPhone')
            } else { // 网关还没有绑定
              commit(globalTypes.UNBINDGATEWAY, 'cti.unBindGateway')
            }
          } else if (code === 406) { // 账号的版本与系统版本不符
            commit(globalTypes.SET_EXIT, 'cti.systemVersionError')
            commit(socketTypes.DISCONNECT_SOCKET) // 结束socket 推送
          } else {
            if (code === '400') { // 登录失败
              commit(globalTypes.SET_EXIT, 'cti.loginError')
              commit(socketTypes.DISCONNECT_SOCKET) // 结束socket 推送
            }
          }
        }
      } else if (_response.SessionID) { // 返回SessionID说明已和ass连接上
        config.uniqueId = _response.SessionID
        let date = new Date()
        let identity = date.valueOf()
        config.currentServerTime = identity - _response.Timestamp * 1000
        config.phonebarConfig = _response.PhonebarConfig
        config.autoBusyTime = _response.AutoBusyTime
        if (_response.UserID) {
          config.userId = _response.UserID
        }
        if (_response.PBX) {
          config.pbx_in_ip = _response.PBX
        }
        if (_response.Account) {
          config.accountId = _response.Account
        }
        config.loginName = config.User || config.user
        config.sipNo = _response.SipNum
        config.monitorUser = _response.MonitorUser
        config.monitorPassword = _response.MonitorPassword
        ctiInit(commit, state, config) // 初始化电话条
        currentPhoneBarConfig = config // 把配置电话条的参数临时存储，用于重连电话条
        dispatch('ctiWaitEvent') // 轮询获取事件
        if (rootState.session.user.channelMail === false || rootState.session.user.channelWx === false) {
          // rootState.session.user.channelMail rootState.session.user.channelWx
          // 这2个值之前是判断是否要通过ass推送微信和邮件的消息，现已弃用，后面若是考虑优化，此判断里的代码都可以删除包括syncChannelSet方法
          let _d1 = {}
          if (rootState.session.user.channelMail === false) {
            _d1.channelMail = false
          } else {
            _d1.channelMail = true
          }
          if (rootState.session.user.channelWx === false) {
            _d1.channelWx = false
          } else {
            _d1.channelWx = true
          }
          syncChannelSet(_d1, function () {}) // 同步ass
        }
      }
    }).catch((err) => {
      console.log(err)
      commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
    })
}

function ctiInit (commit, state, config) { // 初始化电话条
  let phoneData = {
    uniqueId: config.uniqueId,
    currentServerTime: config.currentServerTime,
    autoBusyTime: config.autoBusyTime,
    userId: config.userId,
    pbx_in_ip: config.pbx_in_ip,
    accountId: config.accountId,
    loginName: config.loginName,
    sipNo: config.sipNo,
    monitor: config.monitor,
    user: config.user,
    password: config.password,
    extenType: config.extenType,
    busyType: config.busyType,
    monitorUser: config.monitorUser,
    monitorPassword: config.monitorPassword,
    exten: config.exten
  }
  phoneData.phonebarConfig = {}
  if (config.phonebarConfig) {
    let peerstates = config.phonebarConfig.split(',')
    for (let i = 0; i < peerstates.length; i++) { // 电话条状态配置 eg: 空闲，小休， 注意： 小休和忙碌等繁忙状态的只对技能组生效，直接到坐席的还是能打进来
      let m7Value = m7Language('globalChineseKey.' + peerstates[i].split(':')[1], null, true) || peerstates[i].split(':')[1]
      phoneData.phonebarConfig[peerstates[i].split(':')[0]] = m7Value
    }
  }
  commit(types.BUSYTYPENAME, phoneData.phonebarConfig) // 所有电话条状态名字配置 eg: 小休
  commit(types.PHONE_DATA, {phoneData: phoneData}) // 电话条&&监控常用数据对象
  commit(types.CTI_CURRENTSTATE, state.globalLet._cti_unregister) // 当前电话条状态的下标 和 _cti_stateDescription 结合使用 eg: unregister，dialing
  phonePublishEvent(commit, state, 'toolbarupdate', state.globalLet._cti_stateDescription[state.globalLet._cti_currentState], '')
}

export const ctiWaitEvent = ({commit, state, rootState, dispatch}) => { // 轮询等待事件
  if (ctiIsWaitingEvent) {
    return
  }
  ctiIsWaitingEvent = true // 座席很多的时候，事件很多，会频繁commit到vuex
  let phoneJson = {
    Command: 'Action',
    Action: 'GetState',
    ActionID: 'GetState' + Math.random(),
    SessionID: state.globalLet.phone_data.uniqueId,
    User: state.globalLet.phone_data.userId
  }
  if (!state.globalLet.phone_data.uniqueId || !state.globalLet.phone_data.userId) { // 避免取不到值的时候，连续发送请求
    return
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      waitError = false
      clearInterval(jsonpSetInterval)
      ctiReconnectionCount = 0 // 座席很多的时候，事件很多，会频繁commit到vuex
      if (!response) {
        return
      }
      let datas = response
      let _response = datas.Response
      if (typeof _response !== 'object') {
        _response = datas
      }
      if (_response.Succeed && !_response.HasEvent) {
      } else if (!_response.Succeed) {
        if (_response.Expired) { // 当前会话已失效，需要重新连接电话条
          ctiRelogin(commit, state, rootState, dispatch)
          ctiIsWaitingEvent = false
          return
        }
      } else {
        if (_response.Kick) {
          let comments = ''
          if (_response.Comments) {
            comments = _response.Comments
          }
          commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          commit(globalTypes.SET_KICK_FLAG, true) // socket是否离线
          if (comments === 'ukick' || comments === 'ekick') { // 同时登录踢出
            dispatch('destroyWebrtc')
            commit(globalTypes.SET_EXIT, 'cti.sessionInvalidation1')
          } else if (comments === 'restartKick') { // 客户正在使用系统时，状态服务器重启，6S后提示异常并且重连电话条
            window.setTimeout(function () {
              ctiIsWaitingEvent = false
              ctiRelogin(commit, state, rootState, dispatch)
              commit(globalTypes.SET_ERROR, 'cti.serviceFailToRelogin')
            }, 60000)
            return
          } else { // 管理员强制签出
            commit(globalTypes.SET_EXIT, 'cti.sessionInvalidation2')
          }
          commit(globalTypes.LOGINED, false)
          return
        } else {
          let events = datas.Event
          if (events != null) { // 有新事件
            ctiEventHandler(events, state, commit, rootState, dispatch)
          }
        }
      }
      ctiIsWaitingEvent = false
      dispatch('ctiWaitEvent')
    }).catch((err) => {
      if (!waitError) {
        console.log(err)
        waitError = true
        jsonpSetInterval = window.setInterval(function () {
          console.log('错误请求' + ctiReconnectionCount + '次')
          let currentCount = ctiReconnectionCount + 1
          if (currentCount > 30 && currentCount % 30 === 1) { // 断线每30次向用户提示重连
            commit(globalTypes.SET_ERROR, 'cti.connectServiceTimeout')
          }
          ctiReconnectionCount = currentCount
          ctiIsWaitingEvent = false
          dispatch('ctiWaitEvent')
        }, 1000)
      }
    })
}

function ctiEventHandler (evtJsons, state, commit, rootState, dispatch) { // 新的事件推送
  for (let i = 0; i < evtJsons.length; i++) {
    ctiNewEvent(evtJsons[i], state, commit, rootState, dispatch)
  }
}

function ctiNewEvent (evtJson, state, commit, rootState, dispatch) {
  ctiStateProcess(evtJson, state, commit, dispatch) // 更新电话条的数据
  monitorAction.ctiMonitorProcess(evtJson, state, commit, rootState, dispatch) // 更新监控数据
}

function ctiStateProcess (evtJson, state, commit, dispatch) {
  if (evtJson.Event === 'RecycleNewMail' || evtJson.Event === 'NewWebchat' || evtJson.Event === 'taskCreate' || evtJson.Event === 'taskComplete' || evtJson.Event === 'custAssign' || evtJson.Event === 'businessAssignRole' || evtJson.Event === 'businessAssign') {
    // 条件中的事件是已从ass中剥离socket推送
    return
  }
  if (evtJson.Event === 'BindExtenSuccessTipEvent') {
    // 绑定工号 提示用户是否刷新
    commit(types.WORK_NUMBER_BINDING_STATUS, true)
    return
  }
  ctiSuper(evtJson, state, commit, dispatch)
  switch (state.globalLet._cti_currentState) { // 当前电话条状态的下标,0\1\2
    case state.globalLet._cti_unregister: // 0 未连接
      if (evtJson.Event === 'PeerStatus') { // 电话条注册状态
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) { // 若是当前登录的坐席
          if (evtJson.PeerStatus === 'Registered') { // 注册上了
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            ctiUpdate(evtJson, state, commit, dispatch)
          }
        }
      } else if (evtJson.Event === 'UserStatus') { // 坐席状态
        if (state.globalLet.phone_data.userId === evtJson.UserID) { // 是当前坐席
          if (state.globalLet.phone_data.sipNo !== evtJson.SipNum) {
            if (evtJson.PeerStatus === 'Registered') { // 注册上了
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_peerstate: // 1 空闲
      if (evtJson.Event === 'UserBusy') {
        if (state.globalLet.phone_data.userId === evtJson.UserID) {
          commit(types.PHONE_DATA, {phoneData: {busyType: evtJson.BusyType}})
          commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
          ctiUpdate(evtJson, state, commit, dispatch)
        }
      } else if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') {
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Ringing') { // 被呼振铃
            if (evtJson.LinkedChannel && evtJson.LinkedChannel.Data && evtJson.LinkedChannel.Data.TransferReason) {
              let obj = {
                TransferReason: evtJson.LinkedChannel.Data.TransferReason,
                TransferAgent: evtJson.LinkedChannel.Data.TransferAgent
              }
              commit(types.PHONE_TRANSFERREASON, obj)
            }
            if (evtJson.LinkedChannel.ChannelType === 'normal') { // 普通来电
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_belling)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'inner') { // 内部通话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerBelling)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'transfer') { // 来电转接
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transferBelling)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialTransfer') { // 外呼转接
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transferDialing)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          } else if (evtJson.ChannelStatus === 'Ring') { // 呼叫振铃
            if (evtJson.ChannelType === 'dialout') { // 外呼
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialing)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.ChannelType === 'inner') { // 内部通话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerDialing)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.ChannelType === 'listen') { // 监听
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_listening)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'normal') { // 普通来电
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_talking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'threeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'inner') { // 内部通话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialout') { // 外呼
              // 解决在咨询过程中，刷新浏览器
              // if (evtJson.ChannelType === 'inner') {
              //   commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerTalking)
              // }
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'transfer') { // 来电转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialTransfer') { // 外呼转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialoutTransfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          } else if (evtJson.ChannelStatus === 'Up') { // 接起电话
            if (evtJson.ChannelType === 'listen') { // 监听
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_listened)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.ChannelType === 'dialout') {
              // 解决 外呼中 重启 电话条后处理
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialing)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      } else if (evtJson.Event === 'PeerStatus') { // 电话条注册状态
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.PeerStatus !== 'Registered') { // 没有注册上（未连接）
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_unregister)
            ctiUpdate(evtJson, state, commit, dispatch)
          }
        }
      }
      break
    case state.globalLet._cti_dialing: // 2 呼叫中
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            commit('call/SHOW_tRANS_BTN') // 显示转写按钮
            if (evtJson.ChannelType === 'dialout') { // 外呼
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_innerDialing: // 3 呼叫中
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.ChannelType === 'inner') { // 内部通话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_belling: // 4 来电振铃
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            commit('call/SHOW_tRANS_BTN')
            if (evtJson.LinkedChannel.ChannelType === 'normal') { // 普通来电
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_talking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'threeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'transfer') { // 来电转接
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialTransfer') { // 外呼转接
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialoutTransfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_innerBelling: // 5 来电振铃
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'threeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'inner') { // 内部通话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_innerTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_listening: // 6 监听振铃
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) { // 是当前坐席
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Up') { // 接起电话
            if (evtJson.ChannelType === 'listen') { // 监听
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_listened)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_talking: // 7 普通通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'ThreeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_transfer: // 14 转接通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'ThreeWayCall') {  // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_dialoutTransfer: // 15 外呼转接通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'ThreeWayCall') {  // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_threeWayTalking: // 8 三方通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          }
        }
      }
      break
    case state.globalLet._cti_innerTalking: // 9 内部通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          }
        }
      }
      break
    case state.globalLet._cti_dialTalking: // 10 外呼通话
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接诶
            if (evtJson.LinkedChannel.ChannelType === 'ThreeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_listened: // 11 监听中
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          }
        }
      }
      break
    case state.globalLet._cti_transferBelling: // 12 转接振铃
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'normal') { // 普通来电
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_talking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'threeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'transfer') { // 来电转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialTransfer') { // 外呼转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialoutTransfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_transferDialing: // 13 转接振铃
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'normal') { // 普通来电
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_talking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'threeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'transfer') { // 来电转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_transfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            } else if (evtJson.LinkedChannel.ChannelType === 'dialTransfer') { // 外呼转接
              // commit('call/SHOW_tRANS_BTN')
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_dialoutTransfer)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
    case state.globalLet._cti_hold: // 16 保持
      if (evtJson.Event === 'ChannelStatus') { // 解决保持通话，若是客户先挂断电话，电话条不动的问题
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          if (evtJson.ChannelStatus === 'Hangup') { // 挂断操作
            commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
            commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
            commit(types.CALL_IN_FLAG, false) // 来电的标识
            commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
            ctiUpdate(evtJson, state, commit, dispatch)
          } else if (evtJson.ChannelStatus === 'Link') { // 双方建立连接
            if (evtJson.LinkedChannel.ChannelType === 'ThreeWayCall') { // 三方会话
              commit(types.CTI_CURRENTSTATE, state.globalLet._cti_threeWayTalking)
              ctiUpdate(evtJson, state, commit, dispatch)
            }
          }
        }
      }
      break
  }
  let ctiExtenState = state.globalLet._cti_stateDescription[state.globalLet._cti_currentState]
  const extenState = ['dialing', 'talking', 'threeWayTalking', 'dialTalking', 'consultTalking', 'transfer', 'dialTransfer'] // 所有会出现标签的情况
  if (ctiExtenState && extenState.indexOf(ctiExtenState) > -1) {
    commit(types.IS_LABEL_SHOW, true) // 展示标签组件的标识
  }
}

function ctiSuper (evtJson, state, commit, dispatch) { // 每次有新事件过来，都会进此方法（主要是根据判断evtJson.Event进行数据更新）
  if (evtJson.Event === 'UserStatus') { // 事件推送为坐席状态 登录还是退出
    if (state.globalLet.phone_data.userId === evtJson.UserID) {
      commit(types.PHONE_DATA, {phoneData: {busyType: evtJson.BusyType}})
      if (state.globalLet.phone_data.sipNo !== evtJson.SipNum) {
        commit(types.PHONE_DATA, {phoneData: {sipNo: evtJson.SipNum}})
        if (evtJson.PeerStatus === 'Unregistered') { // 未连接，电话条没有注册上
          commit(types.CTI_CURRENTSTATE, state.globalLet._cti_unregister)
          ctiUpdate(evtJson, state, commit, dispatch)
        } else if (evtJson.PeerStatus === 'Registered') { // 已连接，电话条已注册上
          commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate)
          ctiUpdate(evtJson, state, commit, dispatch)
        }
      }
    }
  } else if (evtJson.Event === 'UserBusy') { // 坐席置忙
    if (state.globalLet.phone_data.userId === evtJson.UserID) {
      commit(types.PHONE_DATA, {phoneData: {busyType: evtJson.BusyType}})
    }
  } else if (evtJson.Event === 'ChannelStatus') { // 通话状态 eg: link,Unlink
    if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
      if (evtJson.ChannelStatus === 'Unlink') {
        commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _callId: ''}})
      }
      if (evtJson.ChannelStatus === 'Hangup' && state.globalLet.phone_data.userId === evtJson.UserID) {
        commit(types.VAL_OF_IVR_MENU_DIALOG, {data: '', dialog: false})
      }
      if ((evtJson.ChannelType === 'transfer' || evtJson.ChannelType === 'dialTransfer') && evtJson.ChannelStatus === 'Link') {
        if (evtJson.LinkedChannel && evtJson.LinkedChannel.Data.CallSheetID) {
          commit('call/UPDATE_CURRENT_CDRCALL_INFO', {callSheetId: evtJson.LinkedChannel.Data.CallSheetID, status: 'Link'})
        }
      }
    }
    if (state.globalLet.phone_data.userId === evtJson.UserID) {
      if (evtJson.Data && evtJson.Data.CallSheetID) {
        commit('call/CURRENT_TRANS_ID', {callSheetId: evtJson.Data.CallSheetID})
      }
      if ((evtJson.ChannelType === 'transfer' || evtJson.ChannelType === 'dialTransfer') && evtJson.ChannelStatus === 'Link') {
        if (evtJson.LinkedChannel && evtJson.LinkedChannel.Data.CallSheetID) {
          commit('call/UPDATE_CURRENT_CDRCALL_INFO', {callSheetId: evtJson.LinkedChannel.Data.CallSheetID, status: 'Link'})
        }
      }
    }
    if (evtJson.ChannelStatus === 'Hangup' && state.globalLet.phone_data.userId === evtJson.UserID) { // 挂机&&当前坐席 =》 关闭风控弹窗
      commit('call/CURRENT_TRANS_ID', {callSheetId: ''})
      commit(types.RISK_DIALOG, false)
      commit(types.OUTBOUND_SCREEN_CALL_SHEET_ID, '') // 挂机的时候，清空当前通话的id
      commit(types.IS_LABEL_SHOW, false) // 挂机的时候，展示标签的标识置为false
      commit(types.IS_CALLING, false) // 挂机的时候，通话中的标识清空
      try { // try catch是因为local存储暴了之后，会报错，影响后面的逻辑进行
        window.localStorage.setItem('phoneBarComments', '') // 挂断电话情况备注
      } catch (e) {}
    }
  } else if (evtJson.Event === 'PeerStatus') { // 电话条注册状态
    if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
      if (evtJson.PeerStatus === 'Unregistered') {
        let loginForm = window.sessionStorage.getItem('loginData')
        let rtcData = JSON.parse(loginForm)
        if (rtcData && rtcData.extenType && rtcData.extenType === 'sip') {
          dispatch('initWebRtc', {username: rtcData.loginName, pwd: rtcData.password})
        }
        if (rtcData.token) {
          let loginTokenForm = window.sessionStorage.getItem('tokenLoginData')
          let loginTokenData = JSON.parse(loginTokenForm)
          dispatch('initWebRtc', {username: loginTokenData.loginName, pwd: loginTokenData.password})
        }
      }
      if (state.globalLet._cti_currentState !== state.globalLet._cti_peerstate) { // 当前状态不等于空闲
        return
      }
      if (state.globalLet.phone_data.busyType === state.globalLet._cti_systemBusy) { // 繁忙状态为 99 （系统置忙 or 后处理）
        return
      }
      let peer = ctiGetUserFromSip(evtJson.Exten)
      if (peer) {
        phonePublishEvent(commit, state, 'toolbarupdate', state.globalLet._cti_stateDescription[state.globalLet._cti_currentState], '')
      }
    }
  } else if (evtJson.Event === 'TransferSuccess' || evtJson.Event === 'TransferFailed') { // 转接成功or失败
    evtJson.Type = 'Transfer'
    if (evtJson.Investigate) {
      evtJson.Type = 'Investigate'
    }
    phonePublishEvent(commit, state, 'transfering', evtJson.Event, '')
  } else if (evtJson.Event === 'ConsultSuccess' || evtJson.Event === 'ConsultFailed') {
    // 兼容新的kf咨询通话，如果成功的话 改变电话条的状态 consultTalking是正在咨询中
    commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
    softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
    if (evtJson.Event === 'ConsultSuccess') {
      commit(types.SHOWCONSULTDIALOG, false) // 是否展示咨询弹窗
      commit(globalTypes.SET_SUCCESS, 'cti.consultSuccess')
      phonePublishEvent(commit, state, 'toolbarupdate', 'consultTalking', 'continueTime')
    } else if (evtJson.Event === 'ConsultFailed') {
      commit(globalTypes.SET_ERROR, 'cti.consultError')
    }
  } else if (evtJson.Event === 'IvrMenuEnd') { // 转ivr菜单
    if (evtJson.VAL_OF_IVR_MENU) {
      let outIvrRefused = evtJson.VAL_OF_IVR_MENU
      if (outIvrRefused === 'DTSF') {
        commit(globalTypes.SET_ERROR, 'cti.turnThirdFaild')
      } else {
        commit(types.VAL_OF_IVR_MENU_DIALOG, { data: outIvrRefused, dialog: true })
      }
    }
  }
  // 只有转接和咨询的结果是通过事件推送的，其他的操作，比如转满意度都是action直接返回的
}

function ctiUpdate (evtJson, state, commit, dispatch) {
  let timestamp = ''
  if (evtJson.Event === 'ChannelStatus') {
    if (evtJson.Timestamp) {
      timestamp = evtJson.Timestamp
    }
  } else if (evtJson.Event === 'UserStatus') {
    timestamp = (evtJson.Login ? (evtJson.BusyTimestamp) : '')
  } else if (evtJson.Event === 'UserBusy') {
    timestamp = evtJson.BusyTimestamp
  }
  phonePublishEvent(commit, state, 'toolbarupdate', state.globalLet._cti_stateDescription[state.globalLet._cti_currentState], timestamp)
  switch (state.globalLet._cti_currentState) {
    case state.globalLet._cti_unregister: // 0 未连接
      break
    case state.globalLet._cti_peerstate:
      if (evtJson.Event === 'ChannelStatus') {
        if (evtJson.Exten === state.globalLet.phone_data.sipNo) {
          commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel}})
        }
      }
      break
    case state.globalLet._cti_dialing: // 2 呼叫中
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel}})
      if (evtJson.CalleeProvince !== '') {
        if (!state.globalLet.callingNum && evtJson.FromDid) {
          // 保留重启外呼通话号码
          commit(types.CALLINGNUM, evtJson.FromDid)
        }
        commit(types.CALLEEAREA, evtJson.CalleeProvince + '  ' + evtJson.CalleeCity) // 电话条中的省市
        commit(types.CTI_SHOWNUMBER, true) // 显示正在通话中的号码和省市（直接调用接口外呼的没有正在通话中号码，只有省市）
      }
      // TODO
      break
    case state.globalLet._cti_innerDialing: // 3 呼叫中
      commit(types.CALL_IN_FLAG, true)// 来电的标识（内部通话 eg: 咨询 =》 呼叫中）
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel}})
      // TODO
      break
    case state.globalLet._cti_belling: // 4 来电振铃
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      if (evtJson.Link) {
        let linkedChannel = evtJson.LinkedChannel
        let phoneData = evtJson.Data
        if (state.globalLet._phone_callObject.callId !== linkedChannel.Uniqueid) { // 2个通话id不相等说明是有新的通话
          commit(types.PHONECALLOBJECT, {phoneCallObject: {callId: linkedChannel.Uniqueid}})
          let callsheetid = ''
          let ivrkey = ''
          let phoneCallObject = {
            originCallNo: linkedChannel.FromCid,
            originCalledNo: linkedChannel.FromDid,
            queue: linkedChannel.Queue,
            offeringTime: phoneDateParse(new Date(evtJson.Timestamp * 1000)),
            callerProvince: decodeURIComponent(evtJson.CallerProvince),
            callerCity: decodeURIComponent(evtJson.CallerCity),
            REPEAT_CALL: evtJson.RepeatCall,
            CONNECT_TYPE: 'normal'
          }
          if (phoneData && phoneData.WaitTimeOut && phoneData.transferFromWhenWaitTimeout && phoneData.transferModeWhenWaitTimeout && phoneData.transferToWhenWaitTimeout) {
            phoneCallObject.WaitTimeOut = phoneData.WaitTimeOut
            phoneCallObject.transferFromWhenWaitTimeout = phoneData.transferFromWhenWaitTimeout
            phoneCallObject.transferModeWhenWaitTimeout = phoneData.transferModeWhenWaitTimeout
            phoneCallObject.transferToWhenWaitTimeout = phoneData.transferToWhenWaitTimeout
          }
          if (linkedChannel.Data) {
            if (linkedChannel.Data.CallSheetID) {
              callsheetid = linkedChannel.Data.CallSheetID
              phoneCallObject.callSheetId = callsheetid
            }
            if (linkedChannel.Data.IVRKEY) {
              ivrkey = linkedChannel.Data.IVRKEY
              phoneCallObject.ivrkey = ivrkey
            }
            for (let key in linkedChannel.Data) {
              if (key === 'CallSheetID' || key === 'callSheetID' || key === 'IVRKEY') {
                continue
              }
              phoneCallObject[key] = linkedChannel.Data[key]
            }
          } else {
            phoneCallObject.callSheetId = callsheetid
          }

          let queue = window.phone_queues[phoneCallObject.queue]
          if (queue) {
            phoneCallObject.queueName = queue.queueName
          }
          commit(types.PHONECALLOBJECT, {phoneCallObject: phoneCallObject})
          commit(types.CALL_IN_FLAG, true)// 来电的标识
          dispatch('callItemAdd', phoneCallObject) // 新增来电
        }
      }
      break
    case state.globalLet._cti_innerBelling: // 5 来电振铃
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_listening: // 6 监听振铃
      commit(types.CALL_IN_FLAG, true)// 来电的标识（内部通话 eg: 监听）
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel}})
      // TODO
      break
    case state.globalLet._cti_talking: // 7 普通通话
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_transfer: // 14 转接通话
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_dialoutTransfer: // 15 外呼转接通话
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_threeWayTalking: // 8 三方通话
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_innerTalking: // 9 内部通话
      commit(types.CALL_IN_FLAG, true)// 来电的标识（内部通话 eg: 咨询）
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      // TODO
      break
    case state.globalLet._cti_dialTalking: // 10 外呼通话
      commit(types.CALL_IN_FLAG, true)// 来电的标识（外呼通话 eg: 监控中的抢接）
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      if (evtJson.CalleeProvince !== '') {
        commit(types.CALLEEAREA, evtJson.CalleeProvince + '  ' + evtJson.CalleeCity) // 电话条中的省市
        commit(types.CTI_SHOWNUMBER, true) // 显示正在通话中的号码和省市（直接调用接口外呼的没有正在通话中号码，只有省市）
      }
      if (!state.globalLet.callingNum && evtJson.FromDid) {
        // 保留重启外呼通话号码
        commit(types.CALLINGNUM, evtJson.FromDid)
        commit(types.CTI_SHOWNUMBER, true)
      }
      break
    case state.globalLet._cti_listened: // 11 监听中
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel}})
      break
    case state.globalLet._cti_transferBelling: // 12 转接振铃
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      if (evtJson.Link) {
        let linkedChannel = evtJson.LinkedChannel
        if (state.globalLet._phone_callObject.callId !== linkedChannel.Uniqueid) { // 2个通话id不相等说明是有新的通话
          commit(types.PHONECALLOBJECT, {phoneCallObject: {callId: linkedChannel.Uniqueid}})
          let callsheetid = ''
          let ivrkey = ''
          if (linkedChannel.Data && linkedChannel.Data.CallSheetID) {
            callsheetid = linkedChannel.Data.CallSheetID
          }
          let phoneCallObject = {
            callSheetId: callsheetid,
            originId: linkedChannel.Uniqueid,
            originCallNo: linkedChannel.FromCid,
            originCalledNo: linkedChannel.FromDid,
            callType: linkedChannel.ChannelType,
            callId: linkedChannel.Uniqueid,
            queue: linkedChannel.Queue,
            location: linkedChannel.Location,
            offeringTime: phoneDateParse(new Date(evtJson.Timestamp * 1000)),
            callerProvince: decodeURIComponent(evtJson.CallerProvince),
            callerProvinceCode: evtJson.CallerProvinceCode,
            callerCity: decodeURIComponent(evtJson.CallerCity),
            callerCityCode: evtJson.CallerCityCode,
            REPEAT_CALL: evtJson.RepeatCall,
            data: {},
            status: evtJson.ChannelStatus,
            CONNECT_TYPE: 'transfer' // 来电转接
          }
          if (linkedChannel.Data) {
            phoneCallObject.data = linkedChannel.Data
            phoneCallObject.data.callSheetId = callsheetid
            if (linkedChannel.Data.IVRKEY) {
              ivrkey = linkedChannel.Data.IVRKEY
              phoneCallObject.ivrkey = ivrkey
            }
            for (let key in linkedChannel.Data) {
              if (key === 'CallSheetID' || key === 'callSheetID' || key === 'IVRKEY') {
                continue
              }
              phoneCallObject[key] = linkedChannel.Data[key]
            }
          }
          if (evtJson.Data && evtJson.Data.WaitTimeOut && evtJson.Data.transferFromWhenWaitTimeout && evtJson.Data.transferModeWhenWaitTimeout && evtJson.Data.transferToWhenWaitTimeout) {
            phoneCallObject.WaitTimeOut = evtJson.Data.WaitTimeOut
            phoneCallObject.transferFromWhenWaitTimeout = evtJson.Data.transferFromWhenWaitTimeout
            phoneCallObject.transferModeWhenWaitTimeout = evtJson.Data.transferModeWhenWaitTimeout
            phoneCallObject.transferToWhenWaitTimeout = evtJson.Data.transferToWhenWaitTimeout
          }
          let queue = window.phone_queues[phoneCallObject.queue]
          if (queue) {
            phoneCallObject.queueName = queue.queueName
          }
          commit(types.PHONECALLOBJECT, {phoneCallObject: phoneCallObject})
          commit(types.CALL_IN_FLAG, true)// 来电的标识
          dispatch('callItemAdd', phoneCallObject) // 转接进来的来电
        }
      }
      break
    case state.globalLet._cti_transferDialing: // 13 转接振铃
      commit(types.PHONE_DATA, {phoneData: {_curChannel: evtJson.Channel, _otherChannel: evtJson.LinkedChannel.Channel}})
      if (evtJson.Link) {
        let linkedChannel = evtJson.LinkedChannel
        if (state.globalLet._phone_callObject.callId !== linkedChannel.Uniqueid) { // 2个通话id不相等说明是有新的通话
          commit(types.PHONECALLOBJECT, {phoneCallObject: {callId: linkedChannel.Uniqueid}})
          let callsheetid = ''
          if (linkedChannel.Data && linkedChannel.Data.CallSheetID) {
            callsheetid = linkedChannel.Data.CallSheetID
          }
          let phoneCallObject = {
            callSheetId: callsheetid,
            originId: linkedChannel.Uniqueid,
            originCallNo: linkedChannel.FromCid,
            originCalledNo: linkedChannel.FromDid,
            callType: linkedChannel.ChannelType,
            callId: linkedChannel.Uniqueid,
            queue: linkedChannel.Queue,
            location: linkedChannel.Location,
            offeringTime: phoneDateParse(new Date(evtJson.Timestamp * 1000)),
            callerProvince: decodeURIComponent(evtJson.CallerProvince),
            callerProvinceCode: evtJson.CallerProvinceCode,
            callerCity: decodeURIComponent(evtJson.CallerCity),
            callerCityCode: evtJson.CallerCityCode,
            REPEAT_CALL: evtJson.RepeatCall,
            data: {},
            status: evtJson.ChannelStatus,
            CONNECT_TYPE: 'dialTransfer' // 外呼转接
          }
          if (evtJson.Data && evtJson.Data.WaitTimeOut && evtJson.Data.transferFromWhenWaitTimeout && evtJson.Data.transferModeWhenWaitTimeout && evtJson.Data.transferToWhenWaitTimeout) {
            phoneCallObject.WaitTimeOut = evtJson.Data.WaitTimeOut
            phoneCallObject.transferFromWhenWaitTimeout = evtJson.Data.transferFromWhenWaitTimeout
            phoneCallObject.transferModeWhenWaitTimeout = evtJson.Data.transferModeWhenWaitTimeout
            phoneCallObject.transferToWhenWaitTimeout = evtJson.Data.transferToWhenWaitTimeout
          }
          if (linkedChannel.Data) {
            phoneCallObject.data = linkedChannel.Data
            phoneCallObject.data.callSheetId = callsheetid
          }
          let queue = window.phone_queues[phoneCallObject.queue]
          if (queue) {
            phoneCallObject.queueName = queue.queueName
          }
          commit(types.PHONECALLOBJECT, {phoneCallObject: phoneCallObject})
          commit(types.CALL_IN_FLAG, true)// 来电的标识
          dispatch('callItemAdd', phoneCallObject) // 转接进来的来电
        }
      }
      break
  }
  // TODO publish
}

function phoneDateParse (date) {
  let year = date.getFullYear()
  let month = date.getMonth() + 1
  let day = date.getDate()
  let hour = date.getHours()
  let minute = date.getMinutes()
  return year + '-' + (month > 9 ? month : '0' + month) + '-' + (day > 9 ? day : '0' + day) +
    ' ' + (hour > 9 ? hour : '0' + hour) + ':' + (minute > 9 ? minute : '0' + minute)
}

export function ctiRelogin (commit, state, rootState, dispatch) { // 断网重新注册电话条
  if (isWebsocket) {
    return false
  }
  if (state.globalLet.lockd_state.logoff || !state.globalLet.phone_data.user || state.globalLet._cti_isRelogin) {
    return
  }
  commit(types.CTI_ISRELOGIN, true) // 断网重连中，避免重连action还没返回又再次重连
  let actionBusyType = state.globalLet.phone_data.busyType
  if (actionBusyType === '99') { // 若断网前的状态为后处理，断网重连的时候默认走空闲
    actionBusyType = '0'
  }
  let phoneJson = {
    ipMessage: rootState.session.ipMessage,
    Command: 'Action',
    Action: 'Login',
    ActionID: 'Login' + Math.random(),
    ExtenType: state.globalLet.phone_data.extenType,
    Password: state.globalLet.phone_data.password,
    BusyType: actionBusyType,
    Monitor: state.globalLet.phone_data.monitor,
    User: state.globalLet.phone_data.user,
    AppVersion: 'service'
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        let code = _response.Result
        if (code) {
          if (code === 601) { // 您绑定的licence版本登录座席已达最大限制，请联系客服主管协调/购买licence
            commit(globalTypes.SET_EXIT, 'cti.agentmax')
            commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          } else if (code === 603) { // 您绑定的licence版本因到期无法登录，请联系客服主管协调/续费licence
            commit(globalTypes.SET_EXIT, 'cti.overdue')
            commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          } else if (code === 602) { // 贵司在线咨询方式登录坐席数已达最大或已到期,请使用手机/话机方式登录或联系客服主管购买/续费licence
            commit(globalTypes.SET_EXIT, 'cti.agentmaxOroverdueUserTypeLogin')
            commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          } else if (code === 500) { // 您的网关还没有绑定,请拨打0000进行绑定
            commit(globalTypes.SET_EXIT, 'cti.unBindGateway')
          } else if (code === 406) { // 您账号的版本与系统版本不符，请确定登录地址是您账号所对应的版本！
            commit(globalTypes.SET_EXIT, 'cti.systemVersionError')
            commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          } else { // 登录失败400,通话功能不能使用,请联系管理员
            commit(globalTypes.SET_EXIT, 'cti.loginError')
            commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
          }
        } else { // 您当前的会话已经失效,导致该问题的原因可能是被管理员强制签出
          commit(globalTypes.SET_EXIT, 'cti.sessionInvalidation2')
          commit(socketTypes.DISCONNECT_SOCKET) // socket 推送
        }
      } else if (_response.SessionID) {
        let date = new Date()
        let identity = date.valueOf()
        let phoneData = {
          uniqueId: _response.SessionID,
          currentServerTime: identity - _response.Timestamp * 1000,
          autoBusyTime: _response.AutoBusyTime // 若已挂断电话有个后处理时长
        }
        commit(types.PHONE_DATA, {phoneData: phoneData})
        if (state.globalLet._cti_currentState === state.globalLet._cti_peerstate) {
          if (state.globalLet.phone_data && state.globalLet.phone_data.busyType === '0') { // 空闲
            dispatch('phoneSetBusy', { isBusy: false, busyType: 0 })
          } else if (state.globalLet.phone_data.busyType !== '99') { // 置忙
            dispatch('phoneSetBusy', { isBusy: true, busyType: state.globalLet.phone_data.busyType })
          }
        }
        currentPhoneBarConfig.currentServerTime = phoneData.currentServerTime
        currentPhoneBarConfig.uniqueId = _response.SessionID
        currentPhoneBarConfig.phonebarConfig = _response.PhonebarConfig
        currentPhoneBarConfig.autoBusyTime = _response.AutoBusyTime
        if (_response.UserID) {
          currentPhoneBarConfig.userId = _response.UserID
        }
        if (_response.PBX) {
          currentPhoneBarConfig.pbx_in_ip = _response.PBX
        }
        if (_response.Account) {
          currentPhoneBarConfig.accountId = _response.Account
        }
        currentPhoneBarConfig.sipNo = _response.SipNum
        currentPhoneBarConfig.extenType = state.globalLet.phone_data.extenType
        ctiInit(commit, state, currentPhoneBarConfig)
        commit(types.CTI_CURRENTSTATE, state.globalLet._cti_peerstate) // 注册上电话条后，设置当前状态为空闲 1
        commit(types.CTI_SHOWNUMBER, false) // 隐藏电话条中的通话中号码和省市
        commit(types.CALL_IN_FLAG, false) // 来电的标识
        commit(types.CALLINGNUM, '') // 清空正在通话中的号码 (此代码是为了解决先系统外呼然后调用外呼接口，电话条显示的号码不对的问题修复)
        window.sessionStorage.setItem('phonebarRelogin', 'yes') // 是否断网重连
        dispatch('ctiWaitEvent')
      }
      commit(types.CTI_ISRELOGIN, false) // 重连成功之后去除重连的标志
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
      commit(types.CTI_ISRELOGIN, false) // 异常时去除重连的标志
    })
}
/**
 * 获取推出登陆旁边的通知的未读信息的number  dispatch('syncSysAnnouncement')
 */
export const refreshNoticeUndealNum = ({commit}) => {
  return cti.syncSysAnnouncement().then(res => {
    if (res && res.success) {
      return cti.refreshNoticeUndealNum().then(response => {
        if (response.success) {
          let obj = {
            undealNum: response.undealNum
          }
          commit(types.SET_NOTICE_UNDEALNUM, obj)
        }
      }).catch(err => {
        console.log(err)
        commit(globalTypes.SET_ERROR, err)
      })
    }
  }).catch(err => {
    console.log(err)
    commit(globalTypes.SET_ERROR, err)
  })
}
export const syncSysAnnouncement = ({commit}) => {
  cti.syncSysAnnouncement().then(response => {
    return response
  }).catch(err => {
    console.log(err)
    commit(globalTypes.SET_ERROR, err)
  })
}
/**
 * 通知推送处理
 * @param commit
 * @param state
 * @param rootState
 * @param dispatch
 * @returns {Promise<R>|Promise.<T>}
 * @private
 */
export const noticeEventProcess = ({commit, state, rootState, dispatch}, event) => {
  let obj = {
    undealNum: rootState.cti.globalLet.undealNum + 1
  }
  commit(types.SET_NOTICE_UNDEALNUM, obj)
}
/**
 * 查询通知列表
 * @param data {}
 */
export const getNoticeList = ({ commit, state, rootState }, data) => {
  return cti.getNoticeList(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 查询通过id去查询通知列表的详情
 * @param data {}
 */
export const getNoticeDetailById = ({ commit, state, rootState }, data) => {
  return cti.getNoticeDetailById(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 查询通过id去删除通知列表
 * @param data {}
 */
export const delNotice = ({ commit, state, rootState }, data) => {
  return cti.delNotice(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 清空已读信息
 * @param data {}
 */
export const clearNotice = ({ commit, state, rootState }, data) => {
  return cti.clearNotify(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 将通知全部变为已读
 * @param data {}
 */
export const readNotify = ({ commit, state, rootState }, data) => {
  return cti.readNotify(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 获取折叠通知的详情
 * @param data {}
 */
export const getBusNoyifyList = ({ commit, state, rootState }, data) => {
  return cti.getBusNoyifyList(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 将某一条通知全部变为已读
 * @param data {}
 */
export const readNotifyById = ({ commit, state, rootState }, data) => {
  return cti.readNotify(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
/**
 * 通知全部变为已读
 * @param data {}
 */
export const batchReadNotify = ({ commit, state, rootState }, data) => {
  return cti.batchReadNotify(data)
    .then(response => {
      return response
    })
    .catch(err => {
      console.error(err)
    })
}
export const ctiExit = ({commit, state, rootState, dispatch}, removeQueue) => { // 退出登录
  commit(types.LOCKD_STATE_LOGOFF, true)
  if (!state.globalLet.phone_data.uniqueId) { // 若是不存在ass返回的SessionID，直接退到登录页
    commit(types.PHONE_DATA, {phoneData: ''})
    commit(globalTypes.LOGINED, false)
    window.location = '/'
    // gio('clearUserId')
    return
  }
  let phoneJson = {
    ipMessage: rootState.session.ipMessage,
    Command: 'Action',
    Action: 'Logoff',
    ActionID: 'Logoff' + Math.random(),
    QueueRemove: removeQueue,
    User: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      commit(types.PHONE_DATA, {phoneData: ''})
      commit(globalTypes.LOGINED, false)
      window.location = '/'
      // gio('clearUserId')
    })
}
/**
 * cti-action-monotor.js
 */
export const phoneDialout = ({commit, state, rootState, dispatch}, data) => { // 外呼，全系统的外呼入口走的都是这个接口
  data.phoneNum = strLineAll(data.phoneNum)
  commit(types.CALLINGNUM, data.phoneNum) // 正在通话中的号码
  commit(types.CALLSCREEN_CALLINGNUM, data.phoneNum) // 外呼弹屏中用的正在通话中的号码，和电话条中显示callingNum断开关联
  if (/^\d+$/.test(data.phoneNum)) {
    let firstNum = data.phoneNum.slice(0, 1)
    let callType = ''
    if (data.phoneNum.length < 5) { // 之前判断是4，此次修改是因为工号放开到5位
      let peer = ctiGetUserFromExten(data.phoneNum, state) // 根据工号来匹配监控中可见坐席的信息
      if (!peer) { // 没有匹配上的工号信息，说明是转外线
        data.phoneNum = '9' + data.phoneNum
        callType = 'dialout'
      } else { // 有匹配上的工号信息，说明是转内线（比如： 坐席8019直接转接给坐席8020）
        callType = 'inner'
      }
    } else if (data.phoneNum.length === 5 && firstNum !== '1' && firstNum !== '0' && firstNum !== '9') { // 号码是5位时,并且工号开头不能是1，0，9，判断是内部通话,避免10086等
      callType = 'inner'
    } else { // 大于5位数的号码，直接转外线
      data.phoneNum = '9' + data.phoneNum
      callType = 'dialout'
    }
    let phoneJson = {
      Command: 'Action',
      Action: 'Originate',
      ActionID: 'Originate' + Math.random(),
      Channel: 'SIP/' + state.globalLet.phone_data.sipNo,
      Context: state.globalLet.phone_data.accountId,
      Exten: data.phoneNum,
      Priority: '1',
      UserID: state.globalLet.phone_data.userId,
      Timeout: 60000,
      Async: 'true',
      CallType: callType,
      PBX: state.globalLet.phone_data.pbx_in_ip,
      Account: state.globalLet.phone_data.accountId,
      SessionID: state.globalLet.phone_data.uniqueId
    }
    // if (data.cdrletiable) { // 经搜索没用上，在老版是处理未接来电里面的"回电并处理"
    //   phoneJson.HasCdrlet = 'true'
    //   phoneJson.ActionID = data.cdrletiable + '@' + Math.random()
    // }
    if (data.ques_id) { // 当是问卷模块时需要添加ques_id字段
      phoneJson.ActionID = 'QUES_ID:' + data.ques_id + '@' + Math.random()
      phoneJson.HasCdrVar = 'true'
    }
    const uversion = rootState.session.user.uversion
    const isForbidVersionReuse = rootState.session.account.isForbidVersionReuse // 计费开关
    if (isForbidVersionReuse && (uversion === 'monitor' || uversion === 'service' || uversion === 'service_p')) { //  标准版 || 标准版赠送 || 监控版 全系统都不能外呼
      commit(globalTypes.SET_ERROR, 'cti.currentVersionNoOutbound')
      commit(types.CALLINGNUM, '') // 清空通话中的号码
      commit(types.CALLSCREEN_CALLINGNUM, '') // 清空通话中的号码
      return false
    }
    commit(types.CTI_SHOWNUMBER, true) // 电话条中展示通话中
    cti._cti_sendAction(phoneJson, state).then(response => {
      let _response = response
      if (!_response.Succeed) {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        } else if (_response.IsBlack) { // 接口返回黑名单提示
          MessageBox.confirm(m7Language('cti.numberHasBlack'), {
            showCancelButton: false,
            showConfirmButton: false,
            type: 'warning'
          })
          commit(types.CTI_SHOWNUMBER, false) // 电话条变回空闲
          commit(types.CALLINGNUM, '') // 清空通话中的号码
          commit(types.CALLSCREEN_CALLINGNUM, '') // 清空外呼弹屏中用的正在通话中的号码，和电话条中显示callingNum断开关联
        }
      }
    })
    return true
  } else {
    commit(globalTypes.SET_ERROR, 'cti.phoneNumError')
    return false
  }
}
export const showDialoutUrlOrInPopupCust = ({commit, state, rootState}, data) => {
  // 外呼弹屏数据
  let dialoutUrls = []
  if (data.CallSheetID) {
    commit(types.SCREEN_CALL_SHEET_ID, data.CallSheetID) // 当前外呼弹屏中的通话id,用于新增客户or更新客户or合并客户(通话挂断不清空)
    commit(types.OUTBOUND_SCREEN_CALL_SHEET_ID, data.CallSheetID) // 当前外呼弹屏中的通话id,用于新增客户or更新客户or合并客户（通话挂断清空）
  }
  getCache({commit, state: rootState}, {type: 'dialoutUrls', loadFromServer: true}).then((res) => {
    dialoutUrls = res
    let dialoutUrl = ''
    for (let i = 0; i < dialoutUrls.length; i++) {
      if (dialoutUrls[i].enable === 'true') {
        dialoutUrl = dialoutUrls[i]
      }
    }
    let phoneNum = data.CalledNo
    let callPhone = data.CallNo
    if (dialoutUrl && isHasFunc('func_call_out_interface', rootState)) { // 有开启url对接配置  && 开启外呼弹屏对接的权限
      if (dialoutUrl && dialoutUrl !== '') {
        let business = {}
        if (dialoutUrl.type === '1') {
          business.callType = 'dialoutUrlIn' // 嵌入系统，以弹窗的形式
          business.type = dialoutUrl.type
        } else if (dialoutUrl.type === '2') {
          business.callType = 'dialoutUrlOut'// 弹出的形式
          business.type = dialoutUrl.type
          if (dialoutUrl.outOpenType) {
            business.outOpenType = dialoutUrl.outOpenType
          }
        }
        business.url = dialoutUrl.url
        let callId = data.CallSheetID
        if (business.callType === 'dialoutUrlIn') {
          let urlInData = {'callId': callId, 'phoneNum': phoneNum, 'callPhone': callPhone, 'callBack': function () {}, 'url': business.url, 'data': data}
          if (dialoutUrl.businesses && dialoutUrl.businesses.length > 0) {
            urlInData.businesses = dialoutUrl.businesses
          }
          showDialoutUrlInPopupCust({commit, state, rootState}, urlInData, data) // 外呼对接嵌入
        } else if (business.callType === 'dialoutUrlOut') {
          let urlOutData = {'callId': callId, 'phoneNum': phoneNum, 'callBack': function () {}, 'business': business, 'data': data}
          showCallUrlOutPopupCust({commit, state, rootState}, urlOutData, data)  // 外呼对接弹出
        }
      }
    } else {
      ctiQueryCustomerList({commit, state, rootState}, data) // 弹出客户资料
    }
  })
}

export const phoneHangup = ({commit, state, rootState, dispatch}, data) => { // 挂断
  let phoneJson = {
    Command: 'Action',
    Action: 'Hangup',
    ActionID: 'Hangup' + Math.random(),
    Channel: state.globalLet.phone_data._curChannel,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  if (data) {
    phoneJson.Channel = data.Channel
  }
  let obj = {
    TransferReason: '',
    TransferAgent: ''
  }
  commit(types.PHONE_TRANSFERREASON, obj) // 清空转接原因
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
        if (data) { // 三方之后的挂断客户方或者是被咨询方
          if (_response.Code === 404) { // 设备已挂机的情况
            commit(globalTypes.SET_ERROR, `${data.Exten} 通话已挂断，请确认操作`)
            let autoHangupList = state.globalLet.autoHangupList || []
            let newArr = []
            autoHangupList.forEach(item => {
              if (item.Channel !== data.Channel) {
                newArr.push(item)
              }
            })
            commit(types.AUTO_HANGUP_LIST, newArr) // 设置可主动挂断的列表数据
          } else {
            commit(globalTypes.SET_ERROR, `${data.Exten} 通话挂断失败，请稍后重试`)
          }
        }
      } else if (_response.Succeed && data) { // 挂机成功 && 三方之后的挂断客户方或者是被咨询方
        let autoHangupList = state.globalLet.autoHangupList || []
        let newArr = []
        autoHangupList.forEach(item => {
          if (item.Channel !== data.Channel) {
            newArr.push(item)
          }
        })
        commit(types.AUTO_HANGUP_LIST, newArr) // 设置可主动挂断的列表数据
      }
    })
}

export const phoneHold = ({commit, state, rootState, dispatch}) => { // 保持通话
  let phoneJson = {
    Command: 'Action',
    Action: 'Hold',
    ActionID: 'Hold' + Math.random(),
    Channel: state.globalLet.phone_data._otherChannel,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(types.CTI_ISRELOGIN, state.globalLet._cti_currentState)
        commit(types.CTI_STATEBEFOREHOLD, state.globalLet._cti_currentState)
        commit(types.CTI_CURRENTSTATE, 16) // 16 为通话状态中的"保持"
        phonePublishEvent(commit, state, 'toolbarupdate', 'hold', '')
      } else {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    })
}

export const phoneUnhold = ({commit, state, rootState, dispatch}) => { // 解开/恢复通话
  let phoneJson = {
    Command: 'Action',
    Action: 'Unhold',
    ActionID: 'Unhold' + Math.random(),
    Channel: state.globalLet.phone_data._otherChannel,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(types.CTI_CURRENTSTATE, state.globalLet._cti_stateBeforeHold)
        commit(types.CTI_STATEBEFOREHOLD, '') // 恢复通话时，清空保持通话时记住的状态
        phonePublishEvent(commit, state, 'toolbarupdate', state.globalLet._cti_stateDescription[state.globalLet._cti_stateBeforeHold], '')
      } else {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    })
}
export const markCallSheetThroughCall = ({commit, state, rootState, dispatch}, data) => { // 电话条上打标签
  return cti.markCallSheetThroughCall(data, state)
    .then(
      response => {
        return response
      }
    ).catch(
      (e) => {
        console.log(e)
      }
  )
}

export const phoneConsult = ({commit, state, rootState, dispatch}, data) => { // 咨询
  let phoneJson = {
    Command: 'Action',
    Action: 'Consult',
    Version: 'New',
    ActionID: 'Consult' + Math.random(),
    FromExten: state.globalLet.phone_data.sipNo,
    // Exten: data.phoneNum,
    Timeout: 60000,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  let self = data.self
  delete data.self
  // TODO ask how to solve
  if (data.mode === 'number') {
    if (data.phoneNum.length <= 6) {
      let firstExten = data.exten ? data.exten.slice(0, 1) : ''
      if ((firstExten && firstExten !== '1' && firstExten !== '0' && firstExten !== '9' && data.phoneNum.length === 6) || data.phoneNum.length <= 5) { // 5位号码除了1，0，9开头的以外，其他的都转内线
        data.phoneNum = data.phoneNum.substr(1)
      }
      // 判断 咨询座席  处于忙碌状态且不允许忙碌转接或咨询  提示对方忙碌
      let p1 = getCache({commit, state: rootState}, {type: 'agents'})
      let p2 = getCache({commit, state: rootState}, {type: 'roles'})
      let p = Promise.all([p1, p2])
      p.then(([agents, roles]) => {
        let currentAgents = self.$store.getters.agents || []
        let currentRoles = roles
        for (let i in window.phone_peers) { // 监控中可见的所有的坐席信息
          let peer = window.phone_peers[i]
          let agentRoles = []
          if (peer.exten === data.phoneNum) {
            let notAllowBusyTransferOrConsult = false
            if (currentAgents[i] && currentAgents[i]._id === i) {
              agentRoles = currentAgents[i].role
            }
            for (let k = 0; k < agentRoles.length; k++) {
              for (let j = 0; j < currentRoles.length; j++) {
                if (agentRoles[k] === currentRoles[j]._id) {
                  let role = currentRoles[j]
                  if (role.limits_in.indexOf('func_not_allow_busy_transfer_or_consult') !== -1) { // 我忙碌时，不允许别人转接给我或咨询我
                    notAllowBusyTransferOrConsult = true
                    k = agentRoles.length
                  }
                }
              }
            }
            if (peer.login && peer.busy && notAllowBusyTransferOrConsult) { // 对方忙碌,无法处理您的转接电话
              commit(globalTypes.SET_ERROR, 'cti.busyNoTransfer')
              return
            }
          }
        }
        ctiUiShowTranster(commit, state, data.phoneNum, false)
        phoneJson.Exten = data.phoneNum
        cti._cti_sendAction(phoneJson, state).then(
          response => {
            let _response = response
            if (_response.Succeed) {
              if (_response.Version && _response.Version === 'New') { // _response.IsSupportCancel判断不能写外层，因为IsSupportCancel是后端加了才会显示，其他的还是默认隐藏
                if (_response.IsSupportCancel && _response.IsSupportCancel === 'True') {
                  commit(types.IS_SHOW_CANCLE_COUNSULT_BTN, true) // 显示取消咨询的按钮（其他情况默认隐藏）
                } else {
                  commit(types.IS_SHOW_CANCLE_COUNSULT_BTN, false)
                }
                // 为啦兼容老版电话条 如果有Version说明是新的咨询，需要通过事件来通知是成功还是失败
              } else {
                softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
                commit(globalTypes.SET_SUCCESS, 'cti.consultSuccess')
                commit(types.SHOWCONSULTDIALOG, false) // 是否展示咨询弹窗
                commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
                phonePublishEvent(commit, state, 'toolbarupdate', 'consultTalking', 'continueTime')
              }
            } else {
              softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
              commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
              commit(globalTypes.SET_ERROR, 'cti.consultError')
              if (_response.Expired) { // 当前与ass的链接已失效，重连ass
                ctiRelogin(commit, state, rootState, dispatch)
              }
            }
          }).catch(() => {
            softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
            commit(globalTypes.SET_ERROR, 'cti.consultError')
          })
      }).catch((e) => {
        console.log(e)
      })
    } else {
      ctiUiShowTranster(commit, state, data.phoneNum, false)
      phoneJson.Exten = data.phoneNum
      cti._cti_sendAction(phoneJson, state).then(
        response => {
          let _response = response
          if (_response.Succeed) {
            if (_response.Version && _response.Version === 'New') { // _response.IsSupportCancel判断不能写外层，因为IsSupportCancel是后端加了才会显示，其他的还是默认隐藏
              if (_response.IsSupportCancel && _response.IsSupportCancel === 'True') {
                commit(types.IS_SHOW_CANCLE_COUNSULT_BTN, true) // 显示取消咨询的按钮（其他情况默认隐藏）
              } else {
                commit(types.IS_SHOW_CANCLE_COUNSULT_BTN, false)
              }
              // 为啦兼容老版电话条 如果有Version说明是新的咨询，需要通过事件来通知是成功还是失败
            } else {
              softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
              commit(globalTypes.SET_SUCCESS, 'cti.consultSuccess')
              commit(types.SHOWCONSULTDIALOG, false) // 是否展示咨询弹窗
              commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
              phonePublishEvent(commit, state, 'toolbarupdate', 'consultTalking', 'continueTime')
            }
          } else {
            softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
            commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
            commit(globalTypes.SET_ERROR, 'cti.consultError')
            if (_response.Expired) { // 当前与ass的链接已失效，重连ass
              ctiRelogin(commit, state, rootState, dispatch)
            }
          }
        }).catch(() => {
          softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
          commit(globalTypes.SET_ERROR, 'cti.consultError')
        })
    }
  }
}

export const phoneStopConsult = ({commit, state, rootState, dispatch}) => { // 结束咨询
  let phoneJson = {
    Command: 'Action',
    Action: 'StopConsult',
    ActionID: 'StopConsult' + Math.random(),
    FromExten: state.globalLet.phone_data.sipNo,
    Timeout: 60000,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        if (_response.Message !== undefined) {
          if (response.Message === 'Idle') {
            phonePublishEvent(commit, state, 'toolbarupdate', 'peerstate', 'continueTime')
          } else {
            phonePublishEvent(commit, state, 'toolbarupdate', 'talking', 'continueTime')
          }
        } else {
          phonePublishEvent(commit, state, 'toolbarupdate', 'talking', 'continueTime')
        }
      } else {
        commit(globalTypes.SET_ERROR, 'cti.endConsultError')
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.endConsultError')
    })
}

export const phoneInvestigate = ({commit, state, rootState, dispatch}, nodeNum) => { // 转满意度
  if (state.globalLet._cti_isInvestigatting) { // 转满意度中
    return
  }
  commit(types.CTI_ISINVESTIGATTING, true) // 避免action还没返回又再次发送action
  let phoneJson = {
    Command: 'Action',
    Action: 'Transfer',
    ActionID: 'Transfer' + Math.random(),
    Exten: 's',
    Channel: state.globalLet.phone_data._otherChannel,
    Timeout: 60000,
    CallType: 'investigate',
    UserID: state.globalLet.phone_data.userId,
    Context: state.globalLet.phone_data.accountId + '-investigate',
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  if (nodeNum && nodeNum !== '') {
    phoneJson.Context = state.globalLet.phone_data.accountId + '-' + nodeNum + '-satisfaction'
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        if (response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
      commit(types.CTI_ISINVESTIGATTING, false) // 转满意度成功，取消标志
    }).catch(() => {
      commit(types.CTI_ISINVESTIGATTING, false) // 转满意度异常，取消标志
    })
}

export const phoneTransfer = ({commit, state, rootState, dispatch}, data) => { // 转接
  let phoneJson = {
    Command: 'Action',
    Action: 'Transfer',
    ActionID: 'Transfer' + Math.random(),
    Channel: state.globalLet.phone_data._otherChannel,
    ExtraChannel: state.globalLet.phone_data._curChannel,
    UserID: state.globalLet.phone_data.userId,
    Context: state.globalLet.phone_data.accountId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId,
    TransferReason: data.TransferReason
  }
  let self = data.self
  delete data.self
  let phoneNum = data.phoneNum
  let mode = data.mode

  if (mode === 'number') { // 文本框中输入的或者是快捷下拉选择的工号转接
    if (phoneNum.length <= 6) {
      let firstExten = data.exten ? data.exten.slice(0, 1) : ''
      if ((firstExten && firstExten !== '1' && firstExten !== '0' && firstExten !== '9' && phoneNum.length === 6) || data.phoneNum.length <= 5) { // 5位号码除了1，0，9开头的以外，其他的都转内线
        phoneNum = phoneNum.substr(1)
      }
      // 判断 转接座席  处于忙碌状态且不允许忙碌转接或咨询  提示对方忙碌
      let p1 = getCache({commit, state: rootState}, {type: 'agents'})
      let p2 = getCache({commit, state: rootState}, {type: 'roles'})
      let p = Promise.all([p1, p2])
      p.then(([agents, roles]) => {
        let currentAgents = self.$store.getters.agents || []
        let currentRoles = roles
        for (let i in window.phone_peers) { // 监控中可见的所有的坐席信息
          let peer = window.phone_peers[i]
          let agentRoles = []
          if (peer.exten === phoneNum) {
            let notAllowBusyTransferOrConsult = false
            if (currentAgents[i] && currentAgents[i]._id === i) {
              agentRoles = currentAgents[i].role
            }
            for (let k = 0; k < agentRoles.length; k++) {
              for (let j = 0; j < currentRoles.length; j++) {
                if (agentRoles[k] === currentRoles[j]._id) {
                  let role = currentRoles[j]
                  if (role.limits_in.indexOf('func_not_allow_busy_transfer_or_consult') !== -1) { // 我忙碌时，不允许别人转接给我或咨询我
                    notAllowBusyTransferOrConsult = true
                    k = agentRoles.length
                  }
                }
              }
            }
            if (peer.login && peer.busy && notAllowBusyTransferOrConsult) { // 对方忙碌,无法处理您的转接电话
              commit(globalTypes.SET_ERROR, 'cti.busyNoTransfer')
              return
            }
          }
        }
        ctiUiShowTranster(commit, state, phoneNum, true) // 转接之后的计时弹窗
        phoneJson.Exten = phoneNum
        cti._cti_sendAction(phoneJson, state).then(
          response => {
            let _response = response
            if (_response.Succeed) {
              commit(types.SHOWTRANSFERDIALOG, false)  // 是否展示转接弹窗
            } else {
              commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
              softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
              if (response.Message === '310') { // 转接失败: 未配置外呼线路
                commit(globalTypes.SET_ERROR, 'cti.unline')
              } else if (response.Message === '311') { // 转接失败: 转接的用户忙
                commit(globalTypes.SET_ERROR, 'cti.transferUserBusy')
              } else if (response.Message === '312') { // 转接失败: 转接的用户未签入
                commit(globalTypes.SET_ERROR, 'cti.transferUserCheckOut')
              } else if (response.Message === '313') { // 转接失败: 转接的用户正在通话
                commit(globalTypes.SET_ERROR, 'cti.transferUserOnDial')
              } else if (response.Message === '314') { // 转接失败: 转接的用户没有以通话方式登录
                commit(globalTypes.SET_ERROR, 'cti.transferUserLoginTypeError')
              } else if (response.Message === '315') { // 转接失败: 无法呼通转接的用户
                commit(globalTypes.SET_ERROR, 'cti.dialTransferUserError')
              } else if (response.Message === '316') { // 转接失败: 转接用户不存在
                commit(globalTypes.SET_ERROR, 'cti.transferUserNoExist')
              } else if (response.Message === '318') {
                commit(globalTypes.SET_ERROR, 'cti.AgentAreBanned')
              } else { // 转接失败
                commit(globalTypes.SET_ERROR, 'cti.transferError')
              }
              if (response.Expired) { // 当前与ass的链接已失效，重连ass
                ctiRelogin(commit, state, rootState, dispatch)
              }
            }
          }).catch(() => {
            softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
            commit(globalTypes.SET_ERROR, 'cti.transferError')
          })
      }).catch((e) => {
        console.log(e)
      })
    } else {
      ctiUiShowTranster(commit, state, phoneNum, true) // 转接之后的计时弹窗
      phoneJson.Exten = phoneNum
      cti._cti_sendAction(phoneJson, state).then(
        response => {
          let _response = response
          if (_response.Succeed) {
            commit(types.SHOWTRANSFERDIALOG, false)  // 是否展示转接弹窗
          } else {
            commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
            softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
            if (response.Message === '310') { // 转接失败: 未配置外呼线路
              commit(globalTypes.SET_ERROR, 'cti.unline')
            } else if (response.Message === '311') { // 转接失败: 转接的用户忙
              commit(globalTypes.SET_ERROR, 'cti.transferUserBusy')
            } else if (response.Message === '312') { // 转接失败: 转接的用户未签入
              commit(globalTypes.SET_ERROR, 'cti.transferUserCheckOut')
            } else if (response.Message === '313') { // 转接失败: 转接的用户正在通话
              commit(globalTypes.SET_ERROR, 'cti.transferUserOnDial')
            } else if (response.Message === '314') { // 转接失败: 转接的用户没有以通话方式登录
              commit(globalTypes.SET_ERROR, 'cti.transferUserLoginTypeError')
            } else if (response.Message === '315') { // 转接失败: 无法呼通转接的用户
              commit(globalTypes.SET_ERROR, 'cti.dialTransferUserError')
            } else if (response.Message === '316') { // 转接失败: 转接用户不存在
              commit(globalTypes.SET_ERROR, 'cti.transferUserNoExist')
            } else if (response.Message === '318') {
              commit(globalTypes.SET_ERROR, 'cti.transferUserNoExist')
            } else { // 转接失败
              commit(globalTypes.SET_ERROR, 'cti.transferError')
            }
            if (response.Expired) { // 当前与ass的链接已失效，重连ass
              ctiRelogin(commit, state, rootState, dispatch)
            }
          }
        }).catch(() => {
          softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
          commit(globalTypes.SET_ERROR, 'cti.transferError')
        })
    }
  } else if (mode === 'skillgroup') { // 点击技能组的转接
    ctiUiShowTranster(commit, state, phoneNum, true) // 转接之后的计时弹窗
    phoneJson.Exten = phoneNum
    cti._cti_sendAction(phoneJson, state).then(
      response => {
        let _response = response
        if (_response.Succeed) {
          commit(types.SHOWTRANSFERDIALOG, false)  // 是否展示转接弹窗
        } else {
          commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
          softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
          if (response.Message === '310') {
            commit(globalTypes.SET_ERROR, 'cti.unline')
          } else if (response.Message === '311') {
            commit(globalTypes.SET_ERROR, 'cti.transferUserBusy')
          } else if (response.Message === '312') {
            commit(globalTypes.SET_ERROR, 'cti.transferUserCheckOut')
          } else if (response.Message === '313') {
            commit(globalTypes.SET_ERROR, 'cti.transferUserOnDial')
          } else if (response.Message === '314') {
            commit(globalTypes.SET_ERROR, 'cti.transferUserLoginTypeError')
          } else if (response.Message === '315') {
            commit(globalTypes.SET_ERROR, 'cti.dialTransferUserError')
          } else if (response.Message === '316') {
            commit(globalTypes.SET_ERROR, 'cti.transferUserNoExist')
          } else {
            commit(globalTypes.SET_ERROR, 'cti.transferError')
          }
          if (response.Expired) { // 当前与ass的链接已失效，重连ass
            ctiRelogin(commit, state, rootState, dispatch)
          }
        }
      }).catch(() => {
        softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
        commit(globalTypes.SET_ERROR, 'cti.transferError')
      })
  }
}

function ctiUiShowTranster (commit, state, destExten, isTransfer) { // 转接弹窗
  let waitState = {
    time: '00:00',
    isTransfer: isTransfer,
    Exten: destExten
  }
  commit(types.WAITSATE, waitState)  // 转接或者是咨询后的等待ing
  commit(types.SHOWTRANSFERCANCELDIALOG, true) // 转接或咨询的等待ing弹窗
  let softPhonebarCount = 1
  let ctiUiNotifydialoginterval = window.setInterval(function () {
    let count = softPhonebarCount++
    let time = '00:' + (count < 10 ? '0' + count : count)
    commit(types.WAITSATE, {time: time})  // 转接或者是咨询后的等待ing
    if (state.globalLet_cti_ui_dialogBoxRemain <= 0) {
      softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
    }
    let remain = state.globalLet._cti_ui_dialogBoxRemain - 1000
    commit(types.CTI_UI_DIALOGBOXREMAIN, remain)
  }, 1000)
  commit(types.CTI_UI_NOTIFYDIALOGINTERVAL, ctiUiNotifydialoginterval) // 临时存储转接或咨询ing计时的定时器
}

function softPhonebarClose (state) { // 清除转接或者咨询的弹窗的计时器
  if (state.globalLet._cti_ui_notifyDialogInterval) {
    window.clearInterval(state.globalLet._cti_ui_notifyDialogInterval)
  }
}

export const phoneCancelTransfer = ({commit, state, rootState, dispatch}) => { // 取消转接
  if (state.globalLet.phone_data._otherChannel) {
    let phoneJson = {
      Command: 'Action',
      Action: 'CancelTransfer',
      ActionID: 'CancelTransfer' + Math.random(),
      Channel: state.globalLet.phone_data._otherChannel,
      PBX: state.globalLet.phone_data.pbx_in_ip,
      Account: state.globalLet.phone_data.accountId,
      SessionID: state.globalLet.phone_data.uniqueId
    }
    cti._cti_sendAction(phoneJson, state).then(
      response => {
        let _response = response
        softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
        if (_response.Succeed) {
          commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
          commit(globalTypes.SET_SUCCESS, 'cti.cancelTransferSuccess')
        } else {
          commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
          commit(globalTypes.SET_ERROR, 'cti.cancelTransferError')
          if (response.Expired) { // 当前与ass的链接已失效，重连ass
            ctiRelogin(commit, state, rootState, dispatch)
          }
        }
      }).catch(() => {
        softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
        commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
        commit(globalTypes.SET_ERROR, 'cti.cancelTransferError')
      })
  }
}

export const phoneCancelAdvisory = ({commit, state, rootState, dispatch}, data) => { // 取消咨询
  // _otherChannel当前会话的标志值
  if (state.globalLet.phone_data._otherChannel) {
    let phoneJson = {
      Command: 'Action',
      ConsultExten: data.exten,
      Action: 'CancelConsult',
      FromExten: state.globalLet.phone_data.exten,
      Timeout: 60000,
      ActionID: 'CancelConsult' + Math.random(),
      Channel: state.globalLet.phone_data._otherChannel,
      PBX: state.globalLet.phone_data.pbx_in_ip,
      UserID: state.globalLet.phone_data.userId,
      Account: state.globalLet.phone_data.accountId,
      SessionID: state.globalLet.phone_data.uniqueId
    }
    cti._cti_sendAction(phoneJson, state).then(
      response => {
        let _response = response
        softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
        if (_response.Succeed) {
          commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
          commit(globalTypes.SET_SUCCESS, 'cti.cancelAdvisorySuccess')
        } else {
          commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
          commit(globalTypes.SET_ERROR, 'cti.cancelAdvisoryError')
          // 重连电话条 原因可能是登录失效和断网
          if (response.Expired) {
            ctiRelogin(commit, state, rootState, dispatch)
          }
        }
      }).catch(() => {
        softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
        commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
        commit(globalTypes.SET_ERROR, 'cti.cancelAdvisoryError')
      })
  }
}
export const phoneThreewaycall = ({commit, state, rootState, dispatch}, phoneNum) => { // 三方会话
  commit(types.AUTO_HANGUP_LIST, [])
  phoneNum = phoneNum.substr(1)
  let phoneJson = {
    Command: 'Action',
    Action: 'ThreeWayCall',
    ActionID: 'ThreeWayCall' + Math.random(),
    FromExten: state.globalLet.phone_data.sipNo,
    Exten: phoneNum,
    Timeout: 60000,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(globalTypes.SET_SUCCESS, 'cti.threewaycallSuccess')
        phonePublishEvent(commit, state, 'toolbarupdate', 'threeWayTalking', '') // 电话条ui变更
        if (_response.ThreeWayCallParties && _response.ThreeWayCallParties.length > 0) { // 若pbx升级了，则三方的时候主动发起方可挂断客户或被咨询座席
          commit(types.AUTO_HANGUP_LIST, _response.ThreeWayCallParties || []) // 设置可主动挂断的列表数据
        }
      } else {
        commit(globalTypes.SET_ERROR, 'cti.threewaycallError')
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.threewaycallError')
    })
}

export const phoneKick = ({commit, state, rootState, dispatch}, userId) => { // 签出坐席（监控）
  let phoneJson = {
    Command: 'Action',
    Action: 'Kick',
    ActionID: 'Kick' + Math.random(),
    Exten: userId,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        let peer = window.phone_peers[userId]
        if (peer) {
          peer.C5Status = ''
          peer.callNo = ''
          peer.callStatus = 'Idle'
          let date = new Date()
          let identity = date.valueOf()
          peer.timestamp = identity / 1000
          peer.channel = ''
          peer.linkedChannel = ''
          ctiUpdateQueueInfo(state, commit, rootState)
        }
      } else {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    }).catch(() => {
    })
}

export const phonePick = ({commit, state, rootState, dispatch}, data) => { // 签入手机或sip话机
  let userId = data.userId
  let extenType = data.extenType
  let peer = window.phone_peers[userId]
  if (!extenType) {
    if (peer === null || peer.localNo === null || peer.localNo === '') {
      commit(globalTypes.SET_ERROR, 'cti.agentUnBindlinePhone')
      return {Local: false}
    }
  }
  let phoneJson = {
    Command: 'Action',
    Action: 'SignIn',
    ActionID: 'SignIn' + Math.random(),
    User: userId,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  if (extenType) {
    phoneJson.ExtenType = extenType
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(globalTypes.SET_SUCCESS, 'cti.agentSignInSuccess') // 座席签入成功
      } else {
        if (extenType && extenType === 'gateway') { // 在线客服的登录方式
          if ('isBeyond' in response) {
            commit(globalTypes.SET_ERROR, 'cti.agentFull') // 当前在线座席总数已达最大值，无法再签入
          } else {
            commit(globalTypes.SET_ERROR, 'cti.agentUnBindGateway') // 该座席未绑定网关号或网关号未注册，无法签入
          }
        } else {
          commit(globalTypes.SET_ERROR, 'cti.agentFull') // 当前在线座席总数已达最大值，无法再签入
        }
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    }).catch(() => {
    })
}

export const saveLocalNumForPhonePick = ({commit, state, rootState, dispatch}, data) => { // 保存并签入
  return user.editUser(data)
    .then(response => {
      if (response.success) {
        if (window.phone_peers[data._id]) {
          window.phone_peers[data._id].localNo = data.mobile
          commit(monitorType.AGENT_STATE_CHANGE, data._id)
        }
        phonePick({commit, state, rootState, dispatch}, {userId: data._id})
        return {}
      } else {
        commit(globalTypes.SET_ERROR, 'userInfo.editFail')
      }
    })
    .catch(() => {
      commit(globalTypes.SET_ERROR, 'userInfo.editFail')
    })
}

export const phoneHangupChannel = ({commit, state, rootState, dispatch}, channel) => { // 强拆通话 （监控）（同一个pbx下）
  let phoneJson = {
    Command: 'Action',
    Action: 'Hangup',
    ActionID: 'ForceHangup' + Math.random(),
    Channel: channel,
    Type: 'force',
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state)
}

export const phoneHangupChannelFromPbx = ({commit, state, rootState, dispatch}, data) => { // 强拆通话 （监控）（不同pbx下）
  let channel = data.channel
  let pbx = data.pbx
  let phonePbx = state.globalLet.phone_pbxs[pbx]
  let phoneJson = {
    Command: 'Action',
    Action: 'Hangup',
    ActionID: 'ForceHangup' + Math.random(),
    Channel: channel,
    Type: 'force',
    UserID: state.globalLet.phone_data.userId,
    PBX: pbx,
    Account: state.globalLet.phone_data.accountId,
    SessionID: phonePbx.sessionId
  }
  cti._cti_sendAction(phoneJson, state)
}

export const phoneLoot = ({commit, state, rootState, dispatch}, channel) => { // 抢接
  if (state.globalLet.phone_data.busyType === '0') { // 请先将电话置为忙碌
    commit(globalTypes.SET_ERROR, 'cti.configPhoneBusy')
    return
  }
  let phoneJson = {
    Command: 'Action',
    Action: 'Transfer',
    ActionID: 'Transfer' + Math.random(),
    Exten: state.globalLet.phone_data.exten,
    Channel: channel,
    CallType: 'Loot',
    Context: state.globalLet.phone_data.accountId,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
    }).catch(() => {
    })
}

export const phoneListen = ({commit, state, rootState, dispatch}, curChannel) => { // 监听
  let phoneJson = {
    Command: 'Action',
    Action: 'Originate',
    ActionID: 'Originate' + Math.random(),
    Channel: 'SIP/' + state.globalLet.phone_data.sipNo,
    Application: 'ChanSpy',
    Data: curChannel + '|q',
    Callerid: state.globalLet.phone_data.sipNo,
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        let phoneData = {
          _otherChannel: curChannel
        }
        commit(types.PHONE_DATA, {phoneData: phoneData})
      } else {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
      return true
    }).catch(() => {
    })
}

export const phoneToMenu = ({commit, state, rootState, dispatch}, data) => { // 电话条转ivr菜单
  let exten = data.exten
  let phoneJson = {
    Command: 'Action',
    Action: 'IvrMenu',
    ActionID: 'IvrMenu' + Math.random(),
    Channel: state.globalLet.phone_data._otherChannel,
    Context: exten,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId
  }
  return cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(globalTypes.SET_SUCCESS, 'cti.callPhoneTransferCheck') // 来电正在转验证，请稍后
      } else {
        commit(globalTypes.SET_ERROR, 'cti.transferIvrError') // 转IVR菜单失败
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      }
      return response
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.transferIvrError')
    })
}
//
// export const phonePbxMonitorResister = ({commit, state, rootState, dispatch}, pbx) => { // 弃用，改成ctiRegister了,上线稳定后可直接删除
//   let phoneJson = {
//     Command: 'Action',
//     Action: 'Login',
//     ActionID: 'Login' + Math.random(),
//     PBX: pbx,
//     Account: state.globalLet.phone_data.accountId,
//     UserID: state.globalLet.phone_data.monitorUser,
//     Password: state.globalLet.phone_data.monitorPassword,
//     MonitorUser: true,
//     AppVersion: 'service'
//   }
//   cti._cti_sendAction(phoneJson, state).then(
//     response => {
//       let _response = response
//       let data = {}
//       if (_response.Succeed) {
//         data.sessionId = _response.SessionID
//         data.isWaitingPbxEvent = false
//         data.monitor = true
//         dispatch('phoneWaitPbxEvent', pbx)
//       } else {
//         data.monitor = false
//       }
//       commit(types.PHONE_PBXS, {data: data, type: pbx})
//     }).catch(() => {
//       commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
//       let data = {
//         monitor: false
//       }
//       commit(types.PHONE_PBXS, {data: data, type: pbx})
//     })
// }

// export const phonePbxMonitorLogOff = ({commit, state, rootState, dispatch}, pbx) => {  // 弃用
//
// }
// export const phoneWaitPbxEvent = ({commit, state, rootState, dispatch}, pbx) => { // 弃用，已改成ctiWaitEvent 上线稳定后可直接删除
//   let phonePbx = state.globalLet.phone_pbxs[pbx]
//   if (!phonePbx.monitor) {
//     return
//   }
//   if (phonePbx.isWaitingPbxEvent) {
//     return
//   }
//   commit(types.PHONE_PBXS, {data: {isWaitingPbxEvent: true}, type: pbx})
//   let phoneJson = {
//     Command: 'Action',
//     Action: 'GetState',
//     ActionID: 'GetState' + Math.random(),
//     SessionID: phonePbx.sessionId,
//     User: state.globalLet.phone_data.monitorUser
//   }
//   cti._cti_sendAction(phoneJson, state).then(
//     response => {
//       if (!response) {
//         return
//       }
//       let _response = response.Response
//       if (!_response.Succeed) {
//         if (_response.Expired) {
//           commit(types.PHONE_PBXS, {data: {isWaitingPbxEvent: false}, type: pbx})
//           dispatch('phonePbxMonitorResister', pbx)
//           return
//         }
//       } else if (_response.Succeed && _response.HasEvent) {
//         let events = response.Event
//         if (events !== null) {
//           ctiEventHandler(events, true, state, commit, dispatch)
//         }
//       }
//       commit(types.PHONE_PBXS, {data: {isWaitingPbxEvent: false}, type: pbx})
//       dispatch('phoneWaitPbxEvent', pbx)
//     }).catch(() => {
//       commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
//       commit(types.PHONE_PBXS, {data: {isWaitingPbxEvent: false}, type: pbx})
//     })
// }

export function syncChannelSet (commit, state, data, callback) { // 若是被调用地方的代码去除，此方法也可以去除
  let phoneJson = {
    Command: 'Action',
    Action: 'SetMultiChannelReceiveStatus',
    ActionID: 'SetMultiChannelReceiveStatus' + Math.random(),
    UserID: state.globalLet.phone_data.userId,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    Mail: data.channelMail + '',
    Weixin: data.channelWx + '',
    SessionID: state.globalLet.phone_data.uniqueId
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        if (typeof callback === 'function') {
          callback(response)
        }
      } else {
        commit(globalTypes.SET_ERROR, 'cti.synchronizationAssError')
      }
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.synchronizationAssError')
    })
}

export const phoneSwitchExtenType = ({commit, state, rootState, dispatch}, data) => { // 电话条上切换登录方式
  let phoneJson = {
    Command: 'Action',
    Action: 'SetExtenType',
    ActionID: 'SetExtenType' + Math.random(),
    PBX: rootState.session.user.pbx,
    Account: rootState.session.user.account,
    User: state.globalLet.phone_data.userId,
    ExtenType: data.extenType,
    LoginExten: data.extenNum
  }
  cti._cti_sendAction(phoneJson, state).then(
    response => {
      if (response.Succeed) {
        let sessionData = window.sessionStorage.getItem('loginData')
        if (sessionData) {
          sessionData = JSON.parse(sessionData)
          sessionData.extenType = data.extenType
          window.sessionStorage.setItem('loginData', JSON.stringify(sessionData))
          commit('webrtc/SET_AUTO_SHOW_ANSWER', false)
          if (sessionData && sessionData.extenType && sessionData.extenType === 'sip') {
            dispatch('initWebRtc', {username: sessionData.loginName, pwd: sessionData.password})
          } else {
            dispatch('destroyWebrtc')
          }
        }
        commit(types.PHONE_DATA, {phoneData: {extenType: data.extenType}})
        commit(globalTypes.SET_SUCCESS, 'cti.changeExtenTypeSucess')
      } else {
        commit(globalTypes.SET_ERROR, 'cti.changeExtenTypeError')
      }
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.changeExtenTypeError')
    })
  return true
}

export const phoneSetBusy = ({commit, state, rootState, dispatch}, data) => {
  if (state.globalLet._cti_isSettingbusy) { // 电话条切换状态中
    return
  } else {
    commit(types.CTI_ISSETTINGBUSY, true) // 避免action还没返回又再次发送action
  }
  let phoneJson = {
    Command: 'Action',
    Action: 'Busy',
    ActionID: 'Busy' + Math.random(),
    Exten: data.userId ? data.userId : state.globalLet.phone_data.userId,
    Busy: data.isBusy,
    BusyType: '' + data.busyType,
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId,
    SessionID: state.globalLet.phone_data.uniqueId
  }
  return cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (!_response.Succeed) {
        if (_response.Expired) { // 当前与ass的链接已失效，重连ass
          ctiRelogin(commit, state, rootState, dispatch)
        }
      } else {
        window.sessionStorage.setItem('phoneBarCurrentStatus', data.busyType) // 每次切换状态存储在sessionStorage中，解决在断网超过1分钟之后，电话条没法操作的问题
      }
      commit(types.CTI_ISSETTINGBUSY, false) // 切换状态成功，去除标志
      return response
    }).catch(() => {
      commit(types.CTI_ISSETTINGBUSY, false) // 切换状态异常，去除标志
      return false
    })
}

export const getAllAgentStatus = ({commit, state, rootState, dispatch}, data) => { // 获取所有坐席的空闲状态（电话条转接or咨询时弹窗中的空闲坐席）
  let phoneJson = {
    Action: 'GetAccUserStatus',
    ActionID: 'Busy' + Math.random(),
    PBX: state.globalLet.phone_data.pbx_in_ip,
    Account: state.globalLet.phone_data.accountId
  }
  return cti._cti_sendAction(phoneJson, state).then(
    response => {
      let _response = response
      if (_response.Succeed) {
        commit(types.CTI_ALLAGENTSTATUS, response.UserStatus || []) // 转接或者是咨询时，能知道每个坐席是否空闲
        return response
      }
    }).catch(() => {
      commit(globalTypes.SET_ERROR, 'cti.getAgentStatusFailed') // 获取空闲座席失败
    })
}
function ctiGetUserFromExten (exten, state) { // 根据工号来匹配监控中可见坐席的信息，外呼时phoneDialout能用上此方法（数据对象工号为下标）
  if (!window.phone_peers) {
    return null
  }
  for (let i in window.phone_peers) {
    if (window.phone_peers[i].exten === exten) {
      return window.phone_peers[i]
    }
  }
  return null
}

export function ctiGetUserFromSip (sipNo) { // (数据对象sip号为下标)
  let peer = window._phone_peersFromSip[sipNo]
  if (peer === null || peer === '') { // 根据sip号没有匹配到坐席信息
    if (!window.phone_peers) {
      return null
    }
    for (let i in window.phone_peers) { // 遍历phone_peers(以工号为下标的数据)匹配坐席信息
      if (window.phone_peers[i].sipNo === sipNo) {
        window._phone_peersFromSip[sipNo] = window.phone_peers[i]
        return window._phone_peersFromSip[sipNo]
      }
    }
    return null
  } else { // 根据sip号匹配到了坐席信息,直接返回
    return peer
  }
}

function isHasFunc (key, rootState) { // 获取权限
  let user = rootState.session.user
  if (user.type === 'admin' && user.exten === '0000') {
    let reverse = ['func_hide_tel', 'func_nodelete_customer']
    if (reverse.indexOf(key) !== -1) {
      return false
    } else {
      return true
    }
  }
  let funcIds = user.funcIds
  if (funcIds.indexOf(key) !== -1) {
    return true
  } else {
    return false
  }
}

export function ctiUpdateQueueInfo (state, commit, rootState) {
  for (let i in window.phone_queues) {
    let queueI = window.phone_queues[i]
    let members = queueI.members
    let queueItem = {
      busyAgentCount: 0,
      idleAgentCount: 0,
      registerCount: 0,
      callUserCount: 0,
      unregisterCount: 0
    }
    for (let j in members) {
      let peer = ctiGetUserFromSip(members[j])
      if (peer) {
        if (peer.extenType === 'sip') {
          if (!peer.register || !peer.login || peer.busy || peer.callStatus !== 'Idle') {
            // queueItem.busyAgentCount ++
          } else {
            queueItem.idleAgentCount ++
          }
          if (peer.register) {
            queueItem.registerCount ++
            if (peer.callStatus === 'Idle' && peer.busyType !== '0') {
              queueItem.busyAgentCount ++
            } else if (peer.callStatus !== 'Idle') {
              queueItem.callUserCount ++
            }
          } else {
            queueItem.unregisterCount++
          }
        } else if (peer.extenType === 'gateway') {
          if (!peer.register || peer.busy || peer.callStatus !== 'Idle') {
            // queueItem.busyAgentCount ++
          } else {
            queueItem.idleAgentCount ++
          }
          if (peer.register) {
            queueItem.registerCount ++
            if (peer.callStatus === 'Idle' && peer.busyType !== '0') {
              queueItem.busyAgentCount ++
            } else if (peer.callStatus !== 'Idle') {
              queueItem.callUserCount ++
            }
          } else {
            queueItem.unregisterCount++
          }
        } else if (peer.extenType === 'Local') {
          if (peer.busy || peer.callStatus !== 'Idle') {
            // queueItem.busyAgentCount ++
          } else {
            queueItem.idleAgentCount ++
          }
          if (peer.register) {
            queueItem.registerCount ++
            if (peer.callStatus === 'Idle' && peer.busyType !== '0') {
              queueItem.busyAgentCount ++
            } else if (peer.callStatus !== 'Idle') {
              queueItem.callUserCount ++
            }
          } else {
            queueItem.unregisterCount++
          }
        } else {
          // queueItem.busyAgentCount ++
          if (peer.register) {
            queueItem.registerCount ++
            if (peer.callStatus === 'Idle' && peer.busyType !== '0') {
              queueItem.busyAgentCount ++
            } else if (peer.callStatus !== 'Idle') {
              queueItem.callUserCount ++
            }
          } else {
            queueItem.unregisterCount++
          }
        }
      } else {
        queueItem.idleAgentCount ++
      }
    }
    queueI.busyAgentCount = queueItem.busyAgentCount
    queueI.idleAgentCount = queueItem.idleAgentCount
    queueI.registerCount = queueItem.registerCount
    queueI.callUserCount = queueItem.callUserCount
    queueI.unregisterCount = queueItem.unregisterCount
    commit(types.PHONE_QUEUES)
    phonePublishEvent(commit, state, 'EvtMonitorQueue', [queueI, 'noNeedWaitCount'], '', rootState)
  }
}

/**
 * cti-ui.src.js
 */
export function phonePublishEvent (commit, state, event, param1, param2, rootState) {
  if (event === 'toolbarupdate') {
    ctiUiToolbarupdate(commit, state, param1, param2) // 变更电话条视图（操作按钮）&& 计时变更
  }
  if (event === 'transfering') {
    ctiUiTransfering(commit, state, param1)
  }
  if (param1 && param1[0] && param1[0].queueId) { // 是技能组的变动就调用此方法（电话条上的技能组排队数）
    let phoneData = state.globalLet.phone_data
    let queue = param1[0]
    if (queue.members[phoneData.sipNo]) { // 判断是我所在的技能组
      ctiUiQueue(commit, state, param1, rootState)
    }
  }
}
function ctiUiQueue (commit, state, param1, rootState) { // 电话条上的技能组排队数
  let queue = param1[0]
  if (!rootState.session.myQueue) {
    rootState.session.myQueue = []
  }
  let count = 0
  for (var i = 0; i < rootState.session.myQueue.length; i++) {
    let qid = rootState.session.myQueue[i]
    if (qid === queue.queueId) {
      count++
      break
    }
  }
  if (!count) {
    rootState.session.myQueue.push(queue.queueId)
  }
  if (count > 0) { // 我的技能组
    state.globalLet._cti_ui_all_queue_obj[queue.queueId] = queue.queueWaitCount
    let maqCount = 0
    for (let i in state.globalLet._cti_ui_all_queue_obj) {
      maqCount += state.globalLet._cti_ui_all_queue_obj[i]
    }
    if (state.globalLet.queueNumber === maqCount) { // 若值相同，则不再commit
      return
    }
    if (maqCount > 0) {
      commit(types.QUEUE_NUMBER, maqCount) // 所在技能组通话排队总数
    } else {
      commit(types.QUEUE_NUMBER, 0)
    }
  }
}
function ctiUiTransfering (commit, state, value) {
  if (value === 'TransferSuccess') { // 转接成功
    softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
    commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
    commit(globalTypes.SET_SUCCESS, 'cti.transferSuccess')
    commit('call/CURRENT_TRANS_ID', {callSheetId: ''})
  } else if (value === 'TransferFailed') { // 转接失败
    softPhonebarClose(state) // 清除转接或者咨询的弹窗的计时器
    commit(types.SHOWTRANSFERCANCELDIALOG, false) // 转接或咨询的等待ing弹窗
    commit(globalTypes.SET_ERROR, 'cti.transferError')
  }
}

function ctiUiToolbarupdate (commit, state, lastState, timestamp) { // 变更电话条视图（操作按钮）&& 计时变更
  if (!state.globalLet._cti_ui_last_state) { // 之前没有存储过电话条状态时
    commit(types.CTI_UI_LAST_STATE, lastState) // 存储当前的电话条状态
  }
  ctiUiSwitchState(commit, state, lastState, timestamp) // 状态变更时触发的计时变更
}

function ctiUiSwitchState (commit, state, lastState, timestamp) {
  // 状态变更时触发的计时变更
  let resetTimer = false
  let currentState = state.globalLet._cti_currentState
  if (lastState === 'peerstate') {
    if (state.globalLet._cti_ui_last_state !== lastState) { // 之前的电话条状态和当前的状态不一致时，重置计时
      resetTimer = true
    }
    commit(types.CTI_EXTENSTATE, '')
    if (state.globalLet.phone_data.busyType === '99') { // 后处理状态
      commit(types.TIMING_OR_COUNT_DOWN, 'countDown') // 倒计时
    }
  }
  if (lastState === 'consultTalking' && (currentState === 10 || currentState === 7 || currentState === 15 || currentState === 14)) {
    // currentState === 15 先转接后咨询成功之后操作按钮不对的问题修复
    commit(types.CTI_EXTENSTATE, lastState) // 电话条状态为consultTalking、talking、threeWayTalking时控制icon的展示
  } else if (lastState === 'talking' && currentState === 10) {
    commit(types.CTI_EXTENSTATE, lastState) // 电话条状态为consultTalking、talking、threeWayTalking时控制icon的展示
  } else if (lastState === 'threeWayTalking' && (currentState === 10 || currentState === 7 || currentState === 15 || currentState === 14)) {
    // currentState === 15 先转接后咨询成功之后再转三方后操作按钮不对的问题修复
    commit(types.CTI_EXTENSTATE, lastState) // 电话条状态为consultTalking、talking、threeWayTalking时控制icon的展示
  } else {
    commit(types.CTI_EXTENSTATE, '') // 电话条状态为consultTalking、talking、threeWayTalking时控制icon的展示
  }
  if (state.globalLet.phone_data.busyType === '99' && lastState !== 'dialing' && lastState !== 'dialTalking' && lastState !== 'talking' && lastState !== 'innerTalking' && lastState !== 'transfer' && lastState !== 'dialTransfer') {
    // lastState !== 'dialing' 修复后处理时长倒计时的时候去外呼，没有变回正计时的问题修复（老版也是如此，历史遗留问题）
    return
  }
  if (timestamp === 'continueTime') {
    return
  }
  if (timestamp !== '') {
    let date = new Date()
    let identity = date.valueOf()
    // Math.random() / 10000 是解决 切换oldTime 相同 导致computed不更新
    let oldTime = (((identity - state.globalLet.phone_data.currentServerTime) - parseFloat(timestamp) * 1000) / 1000) + Math.random() / 10000
    if (oldTime < 0) {
      commit(types.CTI_UI_COUNTTIMER, Math.random())
    } else {
      commit(types.CTI_UI_COUNTTIMER, oldTime)
    }
  } else {
    if (resetTimer) {
      commit(types.CTI_UI_COUNTTIMER, Math.random())
    }
  }
  commit(types.TIMING_OR_COUNT_DOWN, 'timing') // 正计时
  commit(types.CTI_UI_LAST_STATE, lastState) // 存储当前的电话条状态
}

export const ctiQueryCustomerList = ({commit, state, rootState, dispatch}, data, Popup) => {
  return new Promise((resolve, reject) => {
    cti.popupCust({phone: data.CalledNo}, state)
      .then(
        response => {
          if (response.success) {
            let customer = {}
            customer.count = response.count || 0
            if (response.list.length < 1) { // 没有匹配上客户（未知客户）
              customer.CUSTOMER_TYPE = 'unk'
            } else if (response.list && response.list.length === 1) { // 匹配上一个客户
              customer.CUSTOMER_ID = response.list[0]._id
              customer.CUSTOMER_STATUS = response.list[0].status
              customer.CUSTOMER_NAME = response.list[0].name
              customer.CUSTOMER_TYPE = 'one'
              customer.list = response.list[0]
              commit(callType.TEMP_CUSTOMER_DATA, {callId: data.CallSheetID, customer: customer.list})
            } else if (response.list && response.list.length > 1) { // 多个匹配客户
              customer.CUSTOMER_TYPE = 'multi'
            }
            let newObj = {}
            Object.assign(newObj, customer, data)
            newObj.CALLED_NO = newObj.CalledNo
            newObj.CALL_NO = newObj.CallNo
            newObj.CALL_SHEET_ID = newObj.CallSheetID
            newObj._id = newObj.CallSheetID
            newObj.CONNECT_TYPE = newObj.CallType
            newObj.PROVINCE = newObj.Province
            newObj.DISTRICT = newObj.District
            newObj.DISTRICT = newObj.District
            newObj.OFFERING_TIME = phoneDateParse(new Date(newObj.Ring * 1000))
            commit(callType.PUSH_CDR_OUTBOUND, newObj)
            commit(types.CALL_CUSTOMER_DETAIL, customer) // 外呼弹屏中的客户数据
            commit(types.CALL_BY_SIP_OR_GETWAY, data.CalledNo)  // sip话机或者是软电话上外呼的号码，重新赋值外呼弹屏中的号码，解决系统内外呼，然后话机外呼之后弹屏号码不对的问题
            const dialPopup = isHasFunc('func_dial_popup', rootState)
            const callDialPopup = isHasFunc('func_call_dial_popup', rootState)
            if (Popup === 'OutPopup' && dialPopup && !callDialPopup) { // 对接url是弹出类型 &&  开启跳通话的权限
              commit(callType.CAll_SCREEN, data.CallSheetID)
            } else {
              if ((callDialPopup && !Popup)) { // 单独弹出客户资料
                commit(types.SCREEN_FLAG, true) // 弹出客户资料
              } else if (dialPopup && !callDialPopup) { // 若开启了外呼弹屏直接跳转到去电详情，若是没开启，默认不跳转
                commit(callType.CAll_SCREEN, data.CallSheetID)
              }
            }
            resolve(customer)
          }
        }
      ).catch(
        (e) => {
          console.log(e)
        })
  })
}

export const getConcurrent = ({commit, state}) => {
  return cti.getConcurrent({}, state).then(
    response => {
      if (response.success) {
        commit(types.LIMITS, response.limit) // 监控呼入并发上限数
      }
    }
  ).catch(
    (e) => {
      console.log(e)
    })
}

export const showDialoutUrlInPopupCust = ({commit, state, rootState}, data, customerData) => { // 外呼弹屏对接（嵌入）参数拼接
  getCache({commit, state: rootState}, {type: 'custTmpls'}).then((res) => {
    let custtmpls = res
    let custmpl = []
    for (let i = 0; i < custtmpls.length; i++) {
      let cust = custtmpls[i]
      if (cust.call_popup && cust.active + '' !== 'false') {
        custmpl.push(cust._id)
      }
    }
    let newData = {accountId: rootState.session.user.account, phone: data.phoneNum, dbType: {$in: custmpl}}
    return cti.popupCust(newData, state).then(
      response => {
        let params = ''
        let account = rootState.session.account
        if (data.data) {
          for (var param in data.data) {
            if (account.encryptionCheck && (param === 'CallNo' || param === 'CalledNo')) {
              let account = rootState.session.account
              if (account.encryType === 'aes') { // aes加密
                params += param + '=' + getAesEncrypt(account.aesSecret, account.aesOffsetValue, data.data[param]) + '&'
              } else { // 默认加密
                let secretKey = account.secretKey
                params += param + '=' + encrypt(secretKey, data.data[param]) + '&'
              }
            } else {
              params += param + '=' + data.data[param] + '&'
            }
          }
          if (rootState.session.user) {
            params += 'loginName=' + rootState.session.user.loginName
          }
          if (account.encryptionCheck && account.encryType === 'aes') { // 开启隐私加密 && aes加密
            params += `&${account.aesOffsetKey || 'iv'}=${account.aesOffsetValue}`
          }
        }
        if (params) {
          params += '&accountId=' + rootState.session.account.account
          if (params.indexOf('#') !== -1) {
            params = params.replace(/#/g, '%23')
          }
          if (data.url.indexOf('?') === -1) {
            data.url += '?' + params
          } else {
            data.url += '&' + params
          }
          if (data.url.indexOf('power.7moor.com') > -1 || data.url.indexOf('power-') > -1) {
            if (rootState.session.sessionId && window.sessionStorage.getItem('loginToken')) {
              data.url += '&sessionId=' + rootState.session.sessionId + '&loginToken=' + window.sessionStorage.getItem('loginToken')
            }
          }
          if (rootState.session.account.tokenCheck) {
            user.getTokenId()
              .then(
                resp => {
                  if (resp.success) {
                    let urlArr = []
                    data.url += '&token=' + resp.token + '&tokenId=' + resp.tokenId
                    let localArr = JSON.parse(window.sessionStorage.getItem('callOutIframeUrl')) || []
                    if (data.businesses && data.businesses.length > 0) {
                      data.businesses.forEach(item => {
                        if (item.url.indexOf('?') === -1) {
                          item.url += '?' + params
                        } else {
                          item.url += '&' + params
                        }
                        item.url += '&token=' + resp.token + '&tokenId=' + resp.tokenId
                        if (item.url.indexOf('power.7moor.com') > -1 || item.url.indexOf('power-') > -1) {
                          if (rootState.session.sessionId && window.sessionStorage.getItem('loginToken')) {
                            item.url += '&sessionId=' + rootState.session.sessionId + '&loginToken=' + window.sessionStorage.getItem('loginToken')
                          }
                        }
                        urlArr.push({urlItem: item.url, name: item.name})
                      })
                    } else {
                      urlArr = [{urlItem: data.url, name: '外呼弹屏'}]
                    }
                    console.log(urlArr)
                    localArr.push({callSheetId: data.callId, url: urlArr})
                    window.sessionStorage.setItem('callOutIframeUrl', JSON.stringify(localArr))
                  }
                }
            )
          } else {
            let urlArr = []
            let localArr = JSON.parse(window.sessionStorage.getItem('callOutIframeUrl')) || []
            if (data.businesses && data.businesses.length > 0) {
              data.businesses.forEach(item => {
                urlArr.push({urlItem: item.url, name: item.name})
              })
            } else {
              urlArr = [{urlItem: data.url, name: '外呼弹屏'}]
            }
            localArr.push({callSheetId: data.callId, url: urlArr})
            window.sessionStorage.setItem('callOutIframeUrl', JSON.stringify(localArr))
          }
        }
        const dialPopup = isHasFunc('func_dial_popup', rootState)
        if (!dialPopup || (dialPopup && isHasFunc('func_call_dial_popup', rootState))) {// 不勾选跳转tab && (跳转tab&&弹窗)
          if (data.businesses && data.businesses.length > 0) {
            commit(types.CALL_SCREEN, data.businesses) // 多类型外呼弹屏对接url
          } else {
            commit(types.CALL_SCREEN, data.url) // 外呼弹屏对接url
          }
        }
        ctiQueryCustomerList({commit, state, rootState}, customerData, 'InPopup') // 弹出客户资料
      }
    ).catch(
      (e) => {
        console.log(e)
      })
  })
}

export const showCallUrlOutPopupCust = ({commit, state, rootState}, data, customerData) => { // 外呼弹屏对接（弹出）参数拼接
  getCache({commit, state: rootState}, {type: 'custTmpls'}).then((res) => {
    let custtmpls = res
    let custmpl = []
    for (let i = 0; i < custtmpls.length; i++) {
      let cust = custtmpls[i]
      if (cust.call_popup && cust.active + '' !== 'false') {
        custmpl.push(cust._id)
      }
    }
    let newData = {accountId: rootState.session.user.account, phone: data.phoneNum, dbType: {$in: custmpl}}
    return cti.popupCust(newData, state).then(
      response => {
        let params = ''
        let account = rootState.session.account
        if (data.data) {
          for (var param in data.data) {
            if (account.encryptionCheck && (param === 'CallNo' || param === 'CalledNo')) {
              let account = rootState.session.account
              if (account.encryType === 'aes') { // aes加密
                params += param + '=' + getAesEncrypt(account.aesSecret, account.aesOffsetValue, data.data[param]) + '&'
              } else { // 默认加密
                let secretKey = account.secretKey
                params += param + '=' + encrypt(secretKey, data.data[param]) + '&'
              }
            } else {
              params += param + '=' + data.data[param] + '&'
            }
          }
          if (rootState.session.user) {
            params += 'loginName=' + rootState.session.user.loginName
          }
          if (account.encryptionCheck && account.encryType === 'aes') { // 开启隐私加密 && aes加密
            params += `&${account.aesOffsetKey || 'iv'}=${account.aesOffsetValue}`
          }
        }
        if (params !== '') {
          if (rootState.session.account.tokenCheck) {
            user.getTokenId()
              .then(
                resp => {
                  if (resp.success) {
                    params += '&token=' + resp.token + '&tokenId=' + resp.tokenId
                    if (params.indexOf('#') !== -1) {
                      params = params.replace(/#/g, '%23')
                    }
                    if (data.business.url.indexOf('?') === -1) {
                      data.business.url += '?' + params
                    } else {
                      data.business.url += '&' + params
                    }
                    if (data.business.url.indexOf('power.7moor.com') > -1 || data.business.url.indexOf('power-') > -1) {
                      if (rootState.session.sessionId && window.sessionStorage.getItem('loginToken')) {
                        data.business.url += '&sessionId=' + rootState.session.sessionId + '&loginToken=' + window.sessionStorage.getItem('loginToken') + '&accountId=' + rootState.session.account.account
                      }
                    }
                    if (data.business.outOpenType) {
                      if (data.business.outOpenType === 'tab') {
                        window.open(data.business.url, '', '')
                      } else {
                        window.open(data.business.url, '', 'fullscreen=yes')
                      }
                    } else {
                      window.open(data.business.url, '', 'fullscreen=yes')
                    }
                  }
                }
              )
          } else {
            if (params.indexOf('#') !== -1) {
              params = params.replace(/#/g, '%23')
            }
            if (data.business.url.indexOf('?') === -1) {
              data.business.url += '?' + params
            } else {
              data.business.url += '&' + params
            }
            if (data.business.url.indexOf('power.7moor.com') > -1 || data.business.url.indexOf('power-') > -1) {
              if (rootState.session.sessionId && window.sessionStorage.getItem('loginToken')) {
                data.business.url += '&sessionId=' + rootState.session.sessionId + '&loginToken=' + window.sessionStorage.getItem('loginToken')
              }
            }
            if (data.business.outOpenType) {
              if (data.business.outOpenType === 'tab') {
                window.open(data.business.url, '', '')
              } else {
                window.open(data.business.url, '', 'fullscreen=yes')
              }
            } else {
              window.open(data.business.url, '', 'fullscreen=yes')
            }
          }
        }
        ctiQueryCustomerList({commit, state, rootState}, customerData, 'OutPopup') // 弹出客户资料
      }).catch(
      (e) => {
        console.log(e)
      })
  })
}

// pbx探测接口 获取pbx支持功能的配置
export const getNewFeatures = ({commit, state, rootState}, pbx) => {
  // let phoneJson = {
  //   Command: 'Action',
  //   Action: 'getNewFeatures'
  // }
  // getCache({commit, state: rootState}, {type: 'accountPbx'}).then((res) => {
  //   if (pbx) {
  //     let assUrl = ''
  //     res.forEach((item, index) => {
  //       if (item._id === pbx) {
  //         assUrl = item.assAddr
  //       }
  //     })
  //     cti._cti_pbx_sendAction(phoneJson, assUrl).then(
  //       response => {
  //         let _response = response
  //         if (_response.Succeed && _response.features && _response.features === 'ChildSatisfaction') {
  //           commit(types.ASS_CURRENT_NEW_FEATURES, true)
  //         } else {
  //           commit(types.ASS_CURRENT_NEW_FEATURES, false)
  //         }
  //       }).catch((err) => {
  //         console.log(err)
  //         commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
  //       })
  //   } else {
  //     if (res && res.length > 0) {
  //       res.forEach((item, index) => {
  //         console.log(item)
  //         cti._cti_pbx_sendAction(phoneJson, item.assAddr).then(
  //           response => {
  //             let _response = response
  //             if (_response.Succeed && _response.features && _response.features === 'ChildSatisfaction') {
  //               commit(types.ASS_NEW_FEATURES, true)
  //             }
  //           }).catch((err) => {
  //             console.log(err)
  //             commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
  //           })
  //       })
  //     }
  //   }
  // })
  if (pbx) {
    cti.childSatisfactionSupport({pbx: pbx}).then((response) => {
      if (response.success && response.support) {
        commit(types.ASS_CURRENT_NEW_FEATURES, true)
      } else {
        commit(types.ASS_CURRENT_NEW_FEATURES, false)
      }
    }).catch((err) => {
      console.log(err)
      commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
    })
  } else {
    cti.childSatisfactionSupport({}).then((response) => {
      if (response.success && response.support) {
        commit(types.ASS_NEW_FEATURES, true)
      }
    }).catch((err) => {
      console.log(err)
      commit(globalTypes.SET_ERROR, 'cti.requestTimeout')
    })
  }
}

